Skip to content

Commit c06127c

Browse files
committed
simplified example in Common Error Scenarios for clarity
1 parent 405fe9e commit c06127c

1 file changed

Lines changed: 37 additions & 109 deletions

File tree

  • python/docs/src/user-guide/core-user-guide/components

python/docs/src/user-guide/core-user-guide/components/tools.ipynb

Lines changed: 37 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -611,128 +611,56 @@
611611
"metadata": {},
612612
"outputs": [],
613613
"source": [
614-
"import json\n",
615-
"from typing import Any, Dict, Optional\n",
616-
"\n",
617-
"import requests\n",
614+
"from typing import Optional\n",
618615
"from typing_extensions import Annotated\n",
619616
"\n",
620-
"\n",
621-
"async def robust_web_search(query: Annotated[str, \"Search query\"]) -> str:\n",
622-
" \"\"\"A robust web search tool that handles various error conditions.\"\"\"\n",
623-
"\n",
617+
"async def weather_forecast(city: Annotated[str, \"City name\"]) -> str:\n",
618+
" \"\"\"Get weather forecast for a city with error handling.\"\"\"\n",
619+
" \n",
624620
" # Input validation\n",
625-
" if not query or not query.strip():\n",
626-
" raise ValueError(\"Search query cannot be empty\")\n",
627-
"\n",
628-
" if len(query) > 500:\n",
629-
" raise ValueError(\"Search query is too long (max 500 characters)\")\n",
630-
"\n",
631-
" try:\n",
632-
" # Simulate API call (replace with actual search API)\n",
633-
" # This is where you would make the actual HTTP request\n",
634-
"\n",
635-
" # Simulate different types of failures\n",
636-
" if \"timeout\" in query.lower():\n",
637-
" raise requests.exceptions.Timeout(\"Search request timed out\")\n",
638-
"\n",
639-
" if \"unauthorized\" in query.lower():\n",
640-
" raise requests.exceptions.HTTPError(\"401 Unauthorized: Invalid API key\")\n",
641-
"\n",
642-
" if \"rate_limit\" in query.lower():\n",
643-
" raise requests.exceptions.HTTPError(\"429 Too Many Requests: Rate limit exceeded\")\n",
644-
"\n",
645-
" # Simulate successful response\n",
646-
" return f\"Search results for '{query}': Found relevant information about the topic.\"\n",
647-
"\n",
648-
" except requests.exceptions.Timeout as e:\n",
649-
" # Handle timeout specifically\n",
650-
" raise TimeoutError(f\"Search request for '{query}' timed out. Please try again.\") from e\n",
651-
"\n",
652-
" except requests.exceptions.HTTPError as e:\n",
653-
" # Handle HTTP errors with specific messages\n",
654-
" if \"401\" in str(e):\n",
655-
" raise PermissionError(\"Search API authentication failed. Please check your API key.\") from e\n",
656-
" elif \"429\" in str(e):\n",
657-
" raise RuntimeError(\"Search API rate limit exceeded. Please wait before trying again.\") from e\n",
658-
" else:\n",
659-
" raise ConnectionError(f\"Search API error: {e}\") from e\n",
660-
"\n",
661-
" except requests.exceptions.RequestException as e:\n",
662-
" # Handle other network-related errors\n",
663-
" raise ConnectionError(f\"Network error during search: {e}\") from e\n",
664-
"\n",
665-
" except Exception as e:\n",
666-
" # Handle any other unexpected errors\n",
667-
" raise RuntimeError(f\"Unexpected error during search: {e}\") from e\n",
668-
"\n",
669-
"\n",
670-
"async def file_processor(file_path: Annotated[str, \"Path to file to process\"]) -> str:\n",
671-
" \"\"\"A file processing tool with comprehensive error handling.\"\"\"\n",
672-
"\n",
621+
" if not city or not city.strip():\n",
622+
" raise ValueError(\"City name cannot be empty\")\n",
623+
" \n",
673624
" try:\n",
674-
" # Simulate file operations\n",
675-
" if not file_path:\n",
676-
" raise ValueError(\"File path cannot be empty\")\n",
677-
"\n",
678-
" if file_path == \"nonexistent.txt\":\n",
679-
" raise FileNotFoundError(f\"File not found: {file_path}\")\n",
680-
"\n",
681-
" if file_path == \"permission_denied.txt\":\n",
682-
" raise PermissionError(f\"Permission denied accessing file: {file_path}\")\n",
683-
"\n",
684-
" if file_path == \"corrupted.txt\":\n",
685-
" raise ValueError(f\"File appears to be corrupted: {file_path}\")\n",
686-
"\n",
687-
" # Simulate successful processing\n",
688-
" return f\"Successfully processed file: {file_path}\"\n",
689-
"\n",
690-
" except FileNotFoundError as e:\n",
691-
" # Re-raise with more context\n",
692-
" raise FileNotFoundError(f\"The file '{file_path}' does not exist. Please check the path and try again.\") from e\n",
693-
"\n",
694-
" except PermissionError as e:\n",
695-
" # Re-raise with helpful message\n",
696-
" raise PermissionError(f\"Access denied to file '{file_path}'. Please check file permissions.\") from e\n",
697-
"\n",
625+
" # Simulate API behavior for demonstration\n",
626+
" if city.lower() == \"error\":\n",
627+
" raise ConnectionError(\"Failed to connect to weather service\")\n",
628+
" \n",
629+
" if city.lower() == \"unknown\":\n",
630+
" raise ValueError(f\"City not found: {city}\")\n",
631+
" \n",
632+
" # Successful case\n",
633+
" return f\"The weather in {city} is sunny with a high of 75°F\"\n",
634+
" \n",
635+
" except ConnectionError as e:\n",
636+
" # Network-related errors\n",
637+
" raise ConnectionError(f\"Network error: {e}. Please try again later.\")\n",
638+
" \n",
698639
" except ValueError as e:\n",
699-
" # Handle validation errors\n",
700-
" raise ValueError(f\"Invalid file or content: {e}\") from e\n",
701-
"\n",
640+
" # Data-related errors\n",
641+
" raise ValueError(f\"Invalid city: {e}\")\n",
642+
" \n",
702643
" except Exception as e:\n",
703-
" # Catch-all for unexpected errors\n",
704-
" raise RuntimeError(f\"Unexpected error processing file '{file_path}': {e}\") from e\n",
705-
"\n",
706-
"\n",
707-
"# Create tools\n",
708-
"search_tool = FunctionTool(robust_web_search, description=\"Search the web for information\")\n",
709-
"file_tool = FunctionTool(file_processor, description=\"Process files\")\n",
710-
"\n",
711-
"# Test different error scenarios\n",
712-
"test_cases = [\n",
713-
" (search_tool, {\"query\": \"python programming\"}), # Success\n",
714-
" (search_tool, {\"query\": \"\"}), # Empty query error\n",
715-
" (search_tool, {\"query\": \"timeout example\"}), # Timeout error\n",
716-
" (file_tool, {\"file_path\": \"document.txt\"}), # Success\n",
717-
" (file_tool, {\"file_path\": \"nonexistent.txt\"}), # File not found\n",
718-
" (file_tool, {\"file_path\": \"permission_denied.txt\"}), # Permission error\n",
719-
"]\n",
644+
" # Unexpected errors\n",
645+
" raise RuntimeError(f\"Unexpected error getting weather: {e}\")\n",
720646
"\n",
721647
"\n",
722-
"async def test_error_handling() -> None:\n",
723-
" \"\"\"Test various error scenarios.\"\"\"\n",
724-
" cancellation_token = CancellationToken()\n",
648+
"# Create the tool\n",
649+
"weather_tool = FunctionTool(weather_forecast, description=\"Get weather forecast for a city\")\n",
725650
"\n",
726-
" for tool, args in test_cases:\n",
651+
"# Test different scenarios\n",
652+
"async def test_weather_tool() -> None:\n",
653+
" cancellation_token = CancellationToken()\n",
654+
" \n",
655+
" for city in [\"New York\", \"\", \"error\", \"unknown\"]:\n",
727656
" try:\n",
728-
" result = await tool.run_json(args, cancellation_token)\n",
729-
" print(f\"{tool.name}: {tool.return_value_as_string(result)}\")\n",
657+
" result = await weather_tool.run_json({\"city\": city}, cancellation_token)\n",
658+
" print(f\"Weather for {city}: {weather_tool.return_value_as_string(result)}\")\n",
730659
" except Exception as e:\n",
731-
" print(f\"❌ {tool.name}: {type(e).__name__}: {e}\")\n",
732-
"\n",
660+
" print(f\"❌ Error for {city}: {type(e).__name__}: {e}\")\n",
733661
"\n",
734662
"# Run the tests\n",
735-
"await test_error_handling()"
663+
"await test_weather_tool()"
736664
]
737665
},
738666
{

0 commit comments

Comments
 (0)