Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
errors.py219 linesDownload Raw Back to langgraph
1from __future__ import annotations2 3from collections.abc import Sequence4from dataclasses import dataclass5from enum import Enum6from typing import Any, Literal7from warnings import warn8 9# EmptyChannelError is re-exported from langgraph.channels.base10from langgraph.checkpoint.base import EmptyChannelError  # noqa: F40111from typing_extensions import deprecated12 13from langgraph.types import Command, Interrupt14from langgraph.warnings import LangGraphDeprecatedSinceV1015 16__all__ = (17    "EmptyChannelError",18    "ErrorCode",19    "GraphDrained",20    "GraphRecursionError",21    "InvalidUpdateError",22    "GraphBubbleUp",23    "GraphInterrupt",24    "NodeError",25    "NodeInterrupt",26    "NodeTimeoutError",27    "ParentCommand",28    "EmptyInputError",29    "TaskNotFound",30)31 32 33class ErrorCode(Enum):34    GRAPH_RECURSION_LIMIT = "GRAPH_RECURSION_LIMIT"35    INVALID_CONCURRENT_GRAPH_UPDATE = "INVALID_CONCURRENT_GRAPH_UPDATE"36    INVALID_GRAPH_NODE_RETURN_VALUE = "INVALID_GRAPH_NODE_RETURN_VALUE"37    MULTIPLE_SUBGRAPHS = "MULTIPLE_SUBGRAPHS"38    INVALID_CHAT_HISTORY = "INVALID_CHAT_HISTORY"39 40 41def create_error_message(*, message: str, error_code: ErrorCode) -> str:42    return (43        f"{message}\n"44        "For troubleshooting, visit: https://docs.langchain.com/oss/python/langgraph/"45        f"errors/{error_code.value}"46    )47 48 49class GraphBubbleUp(Exception):50    pass51 52 53class GraphDrained(GraphBubbleUp):54    """Raised when a graph run exits early due to a drain request.55 56    This indicates the graph stopped cooperatively at a superstep boundary57    because `RunControl.request_drain()` was called (e.g., in response to58    SIGTERM). The checkpoint is saved and the run can be resumed later.59    """60 61    def __init__(self, reason: str = "shutdown") -> None:62        self.reason = reason63        super().__init__(f"Graph drained: {reason}")64 65 66class GraphRecursionError(RecursionError):67    """Raised when the graph has exhausted the maximum number of steps.68 69    This prevents infinite loops. To increase the maximum number of steps,70    run your graph with a config specifying a higher `recursion_limit`.71 72    Troubleshooting guides:73 74    - [`GRAPH_RECURSION_LIMIT`](https://docs.langchain.com/oss/python/langgraph/GRAPH_RECURSION_LIMIT)75 76    Examples:77 78        graph = builder.compile()79        graph.invoke(80            {"messages": [("user", "Hello, world!")]},81            # The config is the second positional argument82            {"recursion_limit": 1000},83        )84    """85 86    pass87 88 89class InvalidUpdateError(Exception):90    """Raised when attempting to update a channel with an invalid set of updates.91 92    Troubleshooting guides:93 94    - [`INVALID_CONCURRENT_GRAPH_UPDATE`](https://docs.langchain.com/oss/python/langgraph/INVALID_CONCURRENT_GRAPH_UPDATE)95    - [`INVALID_GRAPH_NODE_RETURN_VALUE`](https://docs.langchain.com/oss/python/langgraph/INVALID_GRAPH_NODE_RETURN_VALUE)96    """97 98    pass99 100 101class GraphInterrupt(GraphBubbleUp):102    """Raised when a subgraph is interrupted, suppressed by the root graph.103    Never raised directly, or surfaced to the user."""104 105    def __init__(self, interrupts: Sequence[Interrupt] = ()) -> None:106        super().__init__(interrupts)107 108 109@deprecated(110    "NodeInterrupt is deprecated. Please use [`interrupt`][langgraph.types.interrupt] instead.",111    category=None,112)113class NodeInterrupt(GraphInterrupt):114    """Raised by a node to interrupt execution."""115 116    def __init__(self, value: Any, id: str | None = None) -> None:117        warn(118            "NodeInterrupt is deprecated. Please use `langgraph.types.interrupt` instead.",119            LangGraphDeprecatedSinceV10,120            stacklevel=2,121        )122        if id is None:123            super().__init__([Interrupt(value=value)])124        else:125            super().__init__([Interrupt(value=value, id=id)])126 127 128class ParentCommand(GraphBubbleUp):129    args: tuple[Command]130 131    def __init__(self, command: Command) -> None:132        super().__init__(command)133 134 135class EmptyInputError(Exception):136    """Raised when graph receives an empty input."""137 138    pass139 140 141class TaskNotFound(Exception):142    """Raised when the executor is unable to find a task (for distributed mode)."""143 144    pass145 146 147@dataclass(frozen=True, slots=True)148class NodeError:149    """Failure context passed to a node-level error handler.150 151    Inject by adding a parameter typed `NodeError` to a handler registered via152    `StateGraph.add_node(..., error_handler=...)`:153 154    ```python155    def handler(state: State, error: NodeError) -> Command:156        return Command(update={"status": f"recovered from {error.node}: {error.error}"})157    ```158    """159 160    node: str161    """Name of the node whose execution failed."""162 163    error: BaseException164    """Exception raised by the failed node."""165 166 167class NodeTimeoutError(Exception):168    """Raised when a node invocation exceeds one of its configured timeouts.169 170    Does **not** inherit from the built-in `TimeoutError` (a subclass of171    `OSError`) so that the default `RetryPolicy` treats it as retryable.172 173    Both `idle_timeout` and `run_timeout` reflect the configured policy at the174    time of the failure (each is `None` if not configured). `kind` and175    `timeout` identify which one fired.176    """177 178    node: str179    timeout: float180    run_timeout: float | None181    idle_timeout: float | None182    elapsed: float183    kind: Literal["idle", "run"]184 185    def __init__(186        self,187        node: str,188        elapsed: float,189        *,190        kind: Literal["idle", "run"],191        idle_timeout: float | None = None,192        run_timeout: float | None = None,193    ) -> None:194        if kind == "idle":195            if idle_timeout is None:196                raise ValueError("idle_timeout is required when kind='idle'")197            message = (198                f"Node '{node}' exceeded its idle timeout of "199                f"{idle_timeout:.3f}s without making progress "200                f"(elapsed: {elapsed:.3f}s)."201            )202            self.timeout = idle_timeout203        elif kind == "run":204            if run_timeout is None:205                raise ValueError("run_timeout is required when kind='run'")206            message = (207                f"Node '{node}' exceeded its run timeout of "208                f"{run_timeout:.3f}s (elapsed: {elapsed:.3f}s)."209            )210            self.timeout = run_timeout211        else:212            raise ValueError("kind must be 'idle' or 'run'")213        super().__init__(message)214        self.node = node215        self.elapsed = elapsed216        self.kind = kind217        self.idle_timeout = idle_timeout218        self.run_timeout = run_timeout219 
codekingpro/portable-devtools · Team Ai