Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/strands_tools/file_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@
from strands_tools.utils import console_util
from strands_tools.utils.detect_language import detect_language


# Custom Exception for Search if no results are found
class NoResultsFound(Exception):
"""Exception raised when no search results are found."""

pass


# Document format mapping
FORMAT_EXTENSIONS = {
"pdf": [".pdf"],
Expand Down Expand Up @@ -701,6 +709,10 @@ def search_file(console: Console, file_path: str, pattern: str, context_lines: i

results.append({"line_number": i + 1, "context": match_text})

# Check if no results found
if total_matches == 0:
raise NoResultsFound(f"No matches found for pattern '{pattern}' in {os.path.basename(file_path)}")

# Print summary
summary = Panel(
escape(f"Found {total_matches} matches for pattern '{pattern}' in {os.path.basename(file_path)}"),
Expand Down Expand Up @@ -1227,6 +1239,15 @@ def file_read(tool: ToolUse, **kwargs: Any) -> ToolResult:
console.print(history_panel)
response_content.append({"text": f"Time Machine view for {file_path}:\n{history_output}"})

except NoResultsFound as e:
# Handle NoResultsFound specifically to return error status
error_msg = str(e)
console.print(Panel(escape(error_msg), title="[bold yellow]No Results", border_style="yellow"))
return {
"toolUseId": tool_use_id,
"status": "error",
"content": [{"text": error_msg}],
}
except Exception as e:
error_msg = f"Error processing file {file_path}: {str(e)}"
console.print(Panel(escape(error_msg), title="[bold red]Error", border_style="red"))
Expand Down
28 changes: 28 additions & 0 deletions tests/test_file_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,31 @@ def test_file_read_error_message_brackets():
result = file_read.file_read(tool=tool_use)

assert result["status"] == "error"


def test_search_no_results_found_exception(temp_test_file):
"""Test that NoResultsFound exception is raised when search finds no matches."""
console = Console(file=io.StringIO())

with pytest.raises(file_read.NoResultsFound) as exc_info:
file_read.search_file(console, temp_test_file, "NonExistentPattern")

assert "No matches found" in str(exc_info.value)
assert "NonExistentPattern" in str(exc_info.value)


def test_search_no_results_via_tool(temp_test_file):
"""Test that search mode handles NoResultsFound exception gracefully via tool interface."""
tool_use = {
"toolUseId": "test-tool-use-id",
"input": {
"path": temp_test_file,
"mode": "search",
"search_pattern": "PatternThatDoesNotExist",
},
}

result = file_read.file_read(tool=tool_use)

assert result["status"] == "error"
assert "No matches found" in result["content"][0]["text"] or "Error processing file" in result["content"][0]["text"]