An agent that crashes when a tool fails has thrown away the one capability that made it worth building. The model can read an error and try something else — but only if the error reaches it, in a form it can act on, with the retry decision already made by code.

The tool result is the error channel

The default instinct from ordinary software — let the exception propagate — is wrong here. A tool result is a message to a reader. Failure is information that reader needs, and the reader is capable of responding to it. So: catch, format, append as a tool message, continue.

But the message has to be written for the reader, and this is where most implementations lose most of the benefit. Compare:

BAD "Error"