fix: Add helpful error messages for common tool import typos

- Add __getattr__ to crewai_tools/__init__.py to catch common typos
- Provide helpful error message when users try to import tools with lowercase 't' (e.g., PGSearchtool instead of PGSearchTool)
- Add specific error for PGSearchTool indicating it's under development
- Add comprehensive tests to verify error handling

Fixes #3776

Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
Devin AI
2025-10-22 14:34:00 +00:00
parent 4371cf5690
commit 0e0ca6bd08
2 changed files with 79 additions and 0 deletions

View File

@@ -288,3 +288,28 @@ __all__ = [
]
__version__ = "1.1.0"
def __getattr__(name: str):
"""
Catch common typos and provide helpful error messages.
This function is called when an attribute is not found in the module.
It helps users who make common typos when importing tools.
"""
if name == "PGSearchTool":
raise NotImplementedError(
f"'{name}' is currently under development and not yet available. "
f"Please check the CrewAI documentation for updates on when this tool will be released."
)
if name.endswith("tool") and not name.endswith("Tool"):
correct_name = name[:-4] + "Tool"
if correct_name in __all__ or correct_name == "PGSearchTool":
raise ImportError(
f"Cannot import name '{name}' from 'crewai_tools'. "
f"Did you mean '{correct_name}'? "
f"Note: Tool names use capital 'T' in 'Tool'."
)
raise AttributeError(f"module 'crewai_tools' has no attribute '{name}'")

View File

@@ -0,0 +1,54 @@
import pytest
import crewai_tools
def test_typo_in_tool_name_lowercase_t():
"""Test that accessing a tool with lowercase 't' in 'tool' provides a helpful error message."""
with pytest.raises(ImportError) as exc_info:
getattr(crewai_tools, "CSVSearchtool")
assert "Cannot import name 'CSVSearchtool' from 'crewai_tools'" in str(exc_info.value)
assert "Did you mean 'CSVSearchTool'?" in str(exc_info.value)
assert "Tool names use capital 'T' in 'Tool'" in str(exc_info.value)
def test_typo_pgsearchtool_lowercase_t():
"""Test that accessing PGSearchtool (with lowercase 't') provides a helpful error message."""
with pytest.raises(ImportError) as exc_info:
getattr(crewai_tools, "PGSearchtool")
assert "Cannot import name 'PGSearchtool' from 'crewai_tools'" in str(exc_info.value)
assert "Did you mean 'PGSearchTool'?" in str(exc_info.value)
def test_pgsearchtool_not_implemented():
"""Test that accessing PGSearchTool (correct spelling) shows it's not yet implemented."""
with pytest.raises(NotImplementedError) as exc_info:
getattr(crewai_tools, "PGSearchTool")
assert "'PGSearchTool' is currently under development" in str(exc_info.value)
assert "not yet available" in str(exc_info.value)
def test_nonexistent_tool():
"""Test that accessing a completely nonexistent tool gives a standard AttributeError."""
with pytest.raises(AttributeError) as exc_info:
getattr(crewai_tools, "NonExistentTool")
assert "module 'crewai_tools' has no attribute 'NonExistentTool'" in str(exc_info.value)
def test_multiple_typos():
"""Test multiple common typos to ensure they all get helpful messages."""
typos = [
("FileReadtool", "FileReadTool"),
("PDFSearchtool", "PDFSearchTool"),
("MySQLSearchtool", "MySQLSearchTool"),
]
for typo, correct in typos:
with pytest.raises(ImportError) as exc_info:
getattr(crewai_tools, typo)
assert f"Cannot import name '{typo}' from 'crewai_tools'" in str(exc_info.value)
assert f"Did you mean '{correct}'?" in str(exc_info.value)