Skip to content

Commit 7407e9f

Browse files
committed
Enhance error handling in tools to differentiate between recoverable and critical errors, and provide guidelines for handling application-level errors.
1 parent 0737907 commit 7407e9f

File tree

1 file changed

+66
-10
lines changed

1 file changed

+66
-10
lines changed

docs/guides/tools.md

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ chat.ask "What's the weather in New York? Coordinates are 40.7128, -74.0060"
184184

185185
## Error Handling
186186

187-
Tools can handle errors gracefully:
187+
Tools should handle errors differently based on whether they're recoverable by the LLM or require application intervention:
188188

189189
```ruby
190190
class Weather < RubyLLM::Tool
@@ -193,20 +193,76 @@ class Weather < RubyLLM::Tool
193193
param :longitude, desc: "Longitude (e.g., 13.4050)"
194194

195195
def execute(latitude:, longitude:)
196-
url = "https://api.open-meteo.com/v1/forecast?latitude=#{latitude}&longitude=#{longitude}&current=temperature_2m,wind_speed_10m"
197-
198-
response = Faraday.get(url)
199-
data = JSON.parse(response.body)
200-
rescue => e
201-
{ error: e.message }
196+
validate_coordinates!(latitude, longitude)
197+
response = Faraday.get(weather_api_url(latitude, longitude))
198+
199+
case response.status
200+
when 429
201+
# Return errors the LLM should know about and can retry
202+
{ error: "Rate limit exceeded. Please try again in 60 seconds." }
203+
when 200
204+
JSON.parse(response.body)
205+
else
206+
# Let serious problems bubble up
207+
raise "Weather API error: #{response.status}"
208+
end
202209
end
210+
211+
private
212+
def validate_coordinates!(lat, long)
213+
lat = lat.to_f
214+
long = long.to_f
215+
216+
if lat.abs > 90 || long.abs > 180
217+
# Return validation errors to the LLM
218+
{ error: "Invalid coordinates. Latitude must be between -90 and 90, longitude between -180 and 180." }
219+
end
220+
end
221+
222+
def weather_api_url(lat, long)
223+
"https://api.open-meteo.com/v1/forecast?latitude=#{lat}&longitude=#{long}&current=temperature_2m"
224+
end
203225
end
226+
```
227+
228+
Handle application-level errors in your code:
204229

205-
# When there's an error, the model will receive and explain it
206-
chat.ask "What's the weather at invalid coordinates 1000, 1000?"
207-
# => "The coordinates 1000, 1000 are not valid for any location on Earth, as latitude must be between -90 and 90, and longitude must be between -180 and 180. Please provide valid coordinates or a city name for weather information."
230+
```ruby
231+
begin
232+
chat = RubyLLM.chat.with_tool(Weather)
233+
response = chat.ask "What's the weather in Berlin?"
234+
rescue RubyLLM::Error => e
235+
# Handle LLM-specific errors
236+
Rails.logger.error "LLM error: #{e.message}"
237+
raise
238+
rescue StandardError => e
239+
# Handle other unexpected errors
240+
Rails.logger.error "Tool execution failed: #{e.message}"
241+
raise
242+
end
208243
```
209244

245+
### Error Handling Guidelines
246+
247+
When implementing tools, follow these principles:
248+
249+
1. **Return errors to the LLM when:**
250+
- Input validation fails
251+
- The operation can be retried (rate limits, temporary failures)
252+
- Alternative approaches might work
253+
254+
2. **Let errors bubble up when:**
255+
- The tool encounters unexpected states
256+
- System resources are unavailable
257+
- Authentication or authorization fails
258+
- Data integrity is compromised
259+
260+
The LLM can handle returned errors intelligently by:
261+
- Retrying with different parameters
262+
- Suggesting alternative approaches
263+
- Explaining the issue to the user
264+
- Using different tools to accomplish the task
265+
210266
## Simple Tool Parameters
211267

212268
RubyLLM currently only supports simple parameter types: strings, numbers, and booleans. Complex types like arrays and objects are not supported.

0 commit comments

Comments
 (0)