@@ -60,11 +60,23 @@ def start(self, services: InvocationServices, cancel_event: ThreadEvent, profile
60
60
61
61
def run (self , queue_item : SessionQueueItem ):
62
62
"""Run the graph"""
63
- # Loop over invocations until the session is complete or canceled
63
+ # Exceptions raised outside `run_node` are handled by the processor.
64
64
65
65
self ._on_before_run_session (queue_item = queue_item )
66
66
67
+ # Loop over invocations until the session is complete or canceled
67
68
while True :
69
+ # TODO(psyche): Sessions only support errors on nodes, not on the session itself. When an error occurs outside
70
+ # node execution, it bubbles up to the processor where it is treated as a queue item error.
71
+ #
72
+ # Nodes are pydantic models. When we prepare a node in `session.next()`, we set its inputs. This can cause a
73
+ # pydantic validation error. For example, consider a resize image node which has a constraint on its `width`
74
+ # input field - it must be greater than zero. During preparation, if the width is set to zero, pydantic will
75
+ # raise a validation error.
76
+ #
77
+ # When this happens, it breaks the flow before `invocation` is set. We can't set an error on the invocation
78
+ # because we didn't get far enough to get it - we don't know its id. Hence, we just set it as a queue item error.
79
+
68
80
invocation = queue_item .session .next ()
69
81
if invocation is None or self ._cancel_event .is_set ():
70
82
break
@@ -77,7 +89,7 @@ def run(self, queue_item: SessionQueueItem):
77
89
def run_node (self , invocation : BaseInvocation , queue_item : SessionQueueItem ):
78
90
"""Run a single node in the graph"""
79
91
try :
80
- # Any unhandled exception is an invocation error & will fail the graph
92
+ # Any unhandled exception in this scope is an invocation error & will fail the graph
81
93
with self ._services .performance_statistics .collect_stats (invocation , queue_item .session_id ):
82
94
self ._on_before_run_node (invocation , queue_item )
83
95
0 commit comments