Compare commits

...

2 Commits

Author SHA1 Message Date
Devin AI
b5885651de fix: Remove trailing whitespace in docstring
Co-Authored-By: João <joao@crewai.com>
2025-10-22 14:37:41 +00:00
Devin AI
0e0ca6bd08 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>
2025-10-22 14:34:00 +00:00
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)