{ "cells": [ { "cell_type": "code", "id": "initial_id", "metadata": { "collapsed": true, "ExecuteTime": { "end_time": "2026-09-08T07:56:57.833862800Z", "start_time": "2026-09-08T07:56:51.946284300Z" } }, "source": [ "import asyncio\n", "import logging\n", "\n", "from IPython.display import display\n", "from langchain_core.runnables import RunnableConfig\n", "from langgraph.constants import START, END\n", "from langgraph.graph import StateGraph\n", "from langgraph.types import RetryPolicy\n", "from pydantic import BaseModel\n", "from requests import HTTPError\n", "\n", "logger = logging.getLogger(__name__)\n", "\n", "\n", "# 全局状态\n", "class EmptyState(BaseModel):\n", " pass\n", "\n", "async def node_a(state: EmptyState, config: RunnableConfig) -> EmptyState:\n", " print(\"11111111111\")\n", " await asyncio.sleep(5)\n", " raise HTTPError(\"node_a\")\n", "\n", "\n", "builder = StateGraph(state_schema=EmptyState)\n", "builder.add_node(\"node_a\", node_a, retry_policy=RetryPolicy(max_attempts=3), timeout=1)\n", "\n", "builder.add_edge(START, \"node_a\")\n", "builder.add_edge(\"node_a\", END)\n", "\n", "workflow = builder.compile()\n", "try:\n", " result = await workflow.ainvoke({})\n", " # print(result)\n", "except HTTPError as e:\n", " pass\n", "\n", "\n", "display(workflow)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "11111111111\n", "11111111111\n", "11111111111\n" ] }, { "ename": "NodeTimeoutError", "evalue": "Node 'node_a' exceeded its run timeout of 1.000s (elapsed: 1.007s).", "output_type": "error", "traceback": [ "\u001B[31m---------------------------------------------------------------------------\u001B[39m", "\u001B[31mTimeoutError\u001B[39m Traceback (most recent call last)", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\_retry.py:489\u001B[39m, in \u001B[36m_arun_with_timeout\u001B[39m\u001B[34m(task, config, timeout, attempt_ctx, stream)\u001B[39m\n\u001B[32m 488\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m489\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m watchdog\n\u001B[32m 490\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m asyncio.TimeoutError \u001B[38;5;28;01mas\u001B[39;00m exc:\n", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\_retry.py:419\u001B[39m, in \u001B[36m_run_timeout_watchdog\u001B[39m\u001B[34m(run_timeout_s)\u001B[39m\n\u001B[32m 418\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m asyncio.sleep(run_timeout_s)\n\u001B[32m--> \u001B[39m\u001B[32m419\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m asyncio.TimeoutError\n", "\u001B[31mTimeoutError\u001B[39m: ", "\nThe above exception was the direct cause of the following exception:\n", "\u001B[31mNodeTimeoutError\u001B[39m Traceback (most recent call last)", "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[25]\u001B[39m\u001B[32m, line 36\u001B[39m\n\u001B[32m 32\u001B[39m workflow = builder.compile()\n\u001B[32m 33\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m 34\u001B[39m result = \u001B[38;5;28;01mawait\u001B[39;00m workflow.ainvoke({})\n\u001B[32m 35\u001B[39m \u001B[38;5;66;03m# print(result)\u001B[39;00m\n\u001B[32m---> \u001B[39m\u001B[32m36\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m HTTPError \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[32m 37\u001B[39m \u001B[38;5;28;01mpass\u001B[39;00m\n\u001B[32m 38\u001B[39m \n\u001B[32m 39\u001B[39m \n", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\main.py:4090\u001B[39m, in \u001B[36mPregel.ainvoke\u001B[39m\u001B[34m(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, control, version, **kwargs)\u001B[39m\n\u001B[32m 4087\u001B[39m chunks.append(chunk)\n\u001B[32m 4088\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 4089\u001B[39m \u001B[38;5;66;03m# v1: collect interrupts from updates stream\u001B[39;00m\n\u001B[32m-> \u001B[39m\u001B[32m4090\u001B[39m \u001B[38;5;28;01masync\u001B[39;00m \u001B[38;5;28;01mfor\u001B[39;00m chunk \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m.astream(\n\u001B[32m 4091\u001B[39m \u001B[38;5;28minput\u001B[39m,\n\u001B[32m 4092\u001B[39m config,\n\u001B[32m 4093\u001B[39m context=context,\n\u001B[32m 4094\u001B[39m stream_mode=(\n\u001B[32m 4095\u001B[39m [\u001B[33m\"\u001B[39m\u001B[33mupdates\u001B[39m\u001B[33m\"\u001B[39m, \u001B[33m\"\u001B[39m\u001B[33mvalues\u001B[39m\u001B[33m\"\u001B[39m] \u001B[38;5;28;01mif\u001B[39;00m stream_mode == \u001B[33m\"\u001B[39m\u001B[33mvalues\u001B[39m\u001B[33m\"\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m stream_mode\n\u001B[32m 4096\u001B[39m ),\n\u001B[32m 4097\u001B[39m print_mode=print_mode,\n\u001B[32m 4098\u001B[39m output_keys=output_keys,\n\u001B[32m 4099\u001B[39m interrupt_before=interrupt_before,\n\u001B[32m 4100\u001B[39m interrupt_after=interrupt_after,\n\u001B[32m 4101\u001B[39m durability=durability,\n\u001B[32m 4102\u001B[39m control=control,\n\u001B[32m 4103\u001B[39m **kwargs,\n\u001B[32m 4104\u001B[39m ):\n\u001B[32m 4105\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m stream_mode == \u001B[33m\"\u001B[39m\u001B[33mvalues\u001B[39m\u001B[33m\"\u001B[39m:\n\u001B[32m 4106\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(chunk) == \u001B[32m2\u001B[39m:\n", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\main.py:3440\u001B[39m, in \u001B[36mPregel.astream\u001B[39m\u001B[34m(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, control, subgraphs, debug, version, **kwargs)\u001B[39m\n\u001B[32m 3438\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m task \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28;01mawait\u001B[39;00m loop.amatch_cached_writes():\n\u001B[32m 3439\u001B[39m loop.output_writes(task.id, task.writes, cached=\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[32m-> \u001B[39m\u001B[32m3440\u001B[39m \u001B[38;5;28;01masync\u001B[39;00m \u001B[38;5;28;01mfor\u001B[39;00m _ \u001B[38;5;129;01min\u001B[39;00m runner.atick(\n\u001B[32m 3441\u001B[39m [t \u001B[38;5;28;01mfor\u001B[39;00m t \u001B[38;5;129;01min\u001B[39;00m loop.tasks.values() \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m t.writes],\n\u001B[32m 3442\u001B[39m timeout=\u001B[38;5;28mself\u001B[39m.step_timeout,\n\u001B[32m 3443\u001B[39m get_waiter=get_waiter,\n\u001B[32m 3444\u001B[39m schedule_task=loop.aaccept_push,\n\u001B[32m 3445\u001B[39m ):\n\u001B[32m 3446\u001B[39m \u001B[38;5;66;03m# emit output\u001B[39;00m\n\u001B[32m 3447\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m o \u001B[38;5;129;01min\u001B[39;00m _output(\n\u001B[32m 3448\u001B[39m stream_mode,\n\u001B[32m 3449\u001B[39m print_mode,\n\u001B[32m (...)\u001B[39m\u001B[32m 3455\u001B[39m _state_mapper,\n\u001B[32m 3456\u001B[39m ):\n\u001B[32m 3457\u001B[39m \u001B[38;5;28;01myield\u001B[39;00m o\n", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\_runner.py:396\u001B[39m, in \u001B[36mPregelRunner.atick\u001B[39m\u001B[34m(self, tasks, reraise, timeout, retry_policy, get_waiter, schedule_task)\u001B[39m\n\u001B[32m 394\u001B[39m scheduled_error_handler = \u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[32m 395\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m396\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m arun_with_retry(\n\u001B[32m 397\u001B[39m t,\n\u001B[32m 398\u001B[39m retry_policy,\n\u001B[32m 399\u001B[39m stream=\u001B[38;5;28mself\u001B[39m.use_astream,\n\u001B[32m 400\u001B[39m configurable={\n\u001B[32m 401\u001B[39m CONFIG_KEY_CALL: partial(\n\u001B[32m 402\u001B[39m _acall,\n\u001B[32m 403\u001B[39m weakref.ref(t),\n\u001B[32m 404\u001B[39m stream=\u001B[38;5;28mself\u001B[39m.use_astream,\n\u001B[32m 405\u001B[39m retry_policy=retry_policy,\n\u001B[32m 406\u001B[39m futures=weakref.ref(futures),\n\u001B[32m 407\u001B[39m schedule_task=schedule_task,\n\u001B[32m 408\u001B[39m submit=\u001B[38;5;28mself\u001B[39m.submit,\n\u001B[32m 409\u001B[39m loop=loop,\n\u001B[32m 410\u001B[39m ),\n\u001B[32m 411\u001B[39m },\n\u001B[32m 412\u001B[39m )\n\u001B[32m 413\u001B[39m \u001B[38;5;28mself\u001B[39m.commit(t, \u001B[38;5;28;01mNone\u001B[39;00m)\n\u001B[32m 414\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m exc:\n", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\_retry.py:745\u001B[39m, in \u001B[36marun_with_retry\u001B[39m\u001B[34m(task, retry_policy, stream, match_cached_writes, configurable)\u001B[39m\n\u001B[32m 743\u001B[39m \u001B[38;5;28;01mbreak\u001B[39;00m\n\u001B[32m 744\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;01mawait\u001B[39;00m task.proc.ainvoke(task.input, config)\n\u001B[32m--> \u001B[39m\u001B[32m745\u001B[39m result = \u001B[38;5;28;01mawait\u001B[39;00m _arun_with_timeout(\n\u001B[32m 746\u001B[39m task, config, resolved_timeout, attempt_ctx, stream=stream\n\u001B[32m 747\u001B[39m )\n\u001B[32m 748\u001B[39m _finish_timed_attempt(config, attempt_ctx)\n\u001B[32m 749\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m stream:\n\u001B[32m 750\u001B[39m \u001B[38;5;66;03m# if successful, end\u001B[39;00m\n", "\u001B[36mFile \u001B[39m\u001B[32m~\\Desktop\\python-develop\\lotteryServer\\.venv\\Lib\\site-packages\\langgraph\\pregel\\_retry.py:496\u001B[39m, in \u001B[36m_arun_with_timeout\u001B[39m\u001B[34m(task, config, timeout, attempt_ctx, stream)\u001B[39m\n\u001B[32m 494\u001B[39m bg.cancel()\n\u001B[32m 495\u001B[39m bg.add_done_callback(_drain_cancelled)\n\u001B[32m--> \u001B[39m\u001B[32m496\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m NodeTimeoutError(\n\u001B[32m 497\u001B[39m task.name,\n\u001B[32m 498\u001B[39m elapsed,\n\u001B[32m 499\u001B[39m kind=kind,\n\u001B[32m 500\u001B[39m idle_timeout=idle_timeout_s,\n\u001B[32m 501\u001B[39m run_timeout=run_timeout_s,\n\u001B[32m 502\u001B[39m ) \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mexc\u001B[39;00m\n\u001B[32m 503\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mRuntimeError\u001B[39;00m(\n\u001B[32m 504\u001B[39m \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mkind\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m timeout watchdog completed without raising TimeoutError\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 505\u001B[39m )\n\u001B[32m 506\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mRuntimeError\u001B[39;00m(\u001B[33m\"\u001B[39m\u001B[33mtimeout wait completed without task or watchdog\u001B[39m\u001B[33m\"\u001B[39m)\n", "\u001B[31mNodeTimeoutError\u001B[39m: Node 'node_a' exceeded its run timeout of 1.000s (elapsed: 1.007s).", "During task with name 'node_a' and id 'b35c22ae-a4be-38ef-f687-20b76ea2dd87'" ] } ], "execution_count": 25 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }