|
21 | 21 | )
|
22 | 22 | from invokeai.app.services.session_processor.session_processor_common import CanceledException
|
23 | 23 | from invokeai.app.services.session_queue.session_queue_common import SessionQueueItem
|
| 24 | +from invokeai.app.services.shared.graph import NodeInputError |
24 | 25 | from invokeai.app.services.shared.invocation_context import InvocationContextData, build_invocation_context
|
25 | 26 | from invokeai.app.util.profiler import Profiler
|
26 | 27 |
|
@@ -66,18 +67,16 @@ def run(self, queue_item: SessionQueueItem):
|
66 | 67 |
|
67 | 68 | # Loop over invocations until the session is complete or canceled
|
68 | 69 | 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. |
| 70 | + try: |
| 71 | + invocation = queue_item.session.next() |
| 72 | + # Anything other than a `NodeInputError` is handled as a processor error |
| 73 | + except NodeInputError as e: |
| 74 | + # Must extract the exception traceback here to not lose its stacktrace when we change scope |
| 75 | + traceback = e.__traceback__ |
| 76 | + assert traceback is not None |
| 77 | + self._on_node_error(e.node, queue_item, type(e), e, traceback) |
| 78 | + break |
79 | 79 |
|
80 |
| - invocation = queue_item.session.next() |
81 | 80 | if invocation is None or self._cancel_event.is_set():
|
82 | 81 | break
|
83 | 82 | self.run_node(invocation, queue_item)
|
|
0 commit comments