The whole hunk
from line 553, old and new numbered
/
lines
from line 553
553553
554554### Make HTTP requests from hooks
555555
556Hooks can perform asynchronous operations like HTTP requests. Catch errors inside your hook instead of letting them propagate, since an unhandled exception can interrupt the agent.
556Hooks can perform asynchronous operations like HTTP requests. Catch errors inside your hook instead of letting them propagate.
557557
558This example sends a webhook after each tool completes, logging which tool ran and when. The hook catches errors so a failed webhook doesn't interrupt the agent:
558This example sends a webhook after each tool completes, logging which tool ran and when. The hook catches errors from a failed webhook:
559559
560560<CodeGroup>
561561 ```python Python theme={null}
from line 591
591591 # Run the blocking HTTP call in a thread to avoid blocking the event loop
592592 await asyncio.to_thread(_send_webhook, input_data["tool_name"])
593593 except Exception as e:
594 # Log the error but don't raise. A failed webhook shouldn't stop the agent
594 # Log the error but don't raise
595595 print(f"Webhook request failed: {e}")
596596
597597 return {}
from line 620
620620 if (error instanceof Error && error.name === "AbortError") {
621621 console.log("Webhook request cancelled");
622622 }
623 // Don't re-throw. A failed webhook shouldn't stop the agent
623 // Don't re-throw
624624 }
625625
626626 return {};
from line 845
845845
846846A `UserPromptSubmit` hook that spawns subagents can create infinite loops if those subagents trigger the same hook. To prevent this:
847847
848* Check for a subagent indicator in the hook input before spawning
849848* Use a shared variable or session state to track whether you're already inside a subagent
850849* Scope hooks to only run for the top-level agent session
851850