Error envelope

Every tool can fail. Calculator gets malformed input. Weather API times out. The database tool hits a connection pool cap. If each tool raises a different exception type, the orchestrator has to learn every one of them. An envelope fixes that: tools always return a ToolResult with status and payload, and the orchestrator reads the same shape no matter what failed.

layers/tools.py (envelope)
python
from dataclasses import dataclass
from typing import Any, Optional


@dataclass
class ToolResult:
    status: str  # "ok" | "invalid_args" | "tool_error" | "timeout"
    tool: str
    output: Optional[Any] = None
    error: Optional[str] = None


class ToolsLayer:
    def run_envelope(self, tool_name: str, raw_args: dict) -> ToolResult:
        schema = TOOL_SCHEMAS.get(tool_name)
        if schema is None:
            return ToolResult(status="invalid_args", tool=tool_name, error="unknown tool")
        try:
            args = schema(**raw_args)
        except ValidationError as e:
            return ToolResult(status="invalid_args", tool=tool_name, error=str(e.errors()[0]["msg"]))

        try:
            output = self._registry[tool_name](**args.model_dump())
            return ToolResult(status="ok", tool=tool_name, output=output)
        except TimeoutError as e:
            return ToolResult(status="timeout", tool=tool_name, error=str(e))
        except Exception as e:
            return ToolResult(status="tool_error", tool=tool_name, error=str(e))

No raise escapes the tools layer. Every outcome maps to a ToolResult. The orchestrator always reads status first, and the trace always records the same fields.

Matching exercise: Match the failure to the status

Loading practice…

Exceptions cross layer boundaries badly. The orchestrator ends up with a pile of except clauses and no uniform way to record what happened. Envelopes turn every outcome into data, which means the trace entry, the reply fallback, and the metrics pipeline all read the same fields. Use exceptions for programmer errors, use envelopes for expected business outcomes.

Checkpoint: Tools layer checkpoint

Loading practice…