diff --git a/comfy_execution/jobs.py b/comfy_execution/jobs.py index d65936dbd..a8c0eec79 100644 --- a/comfy_execution/jobs.py +++ b/comfy_execution/jobs.py @@ -59,6 +59,7 @@ def normalize_queue_item(item, status): 'create_time': create_time, 'execution_time': None, 'error_message': None, + 'execution_error': None, 'outputs_count': 0, 'preview_output': None, 'workflow_id': None, @@ -84,6 +85,7 @@ def normalize_history_item(prompt_id, history_item, include_outputs=False): outputs_count, preview_output = get_outputs_summary(outputs) error_message = None + execution_error = None if status == JobStatus.ERROR and status_info: messages = status_info.get('messages', []) for entry in messages: @@ -91,6 +93,7 @@ def normalize_history_item(prompt_id, history_item, include_outputs=False): detail = entry[1] if isinstance(detail, dict): error_message = str(detail.get('exception_message', '')) + execution_error = detail break execution_time = history_item.get('execution_time') @@ -112,6 +115,7 @@ def normalize_history_item(prompt_id, history_item, include_outputs=False): job['prompt'] = prompt job['extra_data'] = extra_data job['outputs_to_execute'] = outputs_to_execute + job['execution_error'] = execution_error return job diff --git a/tests/execution/test_jobs.py b/tests/execution/test_jobs.py index 9ffdbb3fb..a4a0dc510 100644 --- a/tests/execution/test_jobs.py +++ b/tests/execution/test_jobs.py @@ -283,6 +283,13 @@ class TestNormalizeHistoryItem: def test_error_job(self): """Error history item should have error status and message.""" + error_detail = { + 'node_id': '5', + 'node_type': 'KSampler', + 'exception_message': 'CUDA out of memory', + 'exception_type': 'RuntimeError', + 'traceback': ['Traceback...', 'RuntimeError: CUDA out of memory'], + } history_item = { 'prompt': ( 5, @@ -295,16 +302,24 @@ class TestNormalizeHistoryItem: 'status_str': 'error', 'completed': False, 'messages': [ - ('execution_error', {'exception_message': 'Node failed: OutOfMemory', 'node_id': '5'}) + ('execution_error', error_detail) ] }, 'outputs': {}, 'execution_time': 1.0, } - job = normalize_history_item('prompt-789', history_item) + # List view - no execution_error + job = normalize_history_item('prompt-789', history_item) assert job['status'] == 'error' - assert job['error_message'] == 'Node failed: OutOfMemory' + assert job['error_message'] == 'CUDA out of memory' + assert 'execution_error' not in job + + # Detail view - includes execution_error + job_detail = normalize_history_item('prompt-789', history_item, include_outputs=True) + assert job_detail['execution_error'] == error_detail + assert job_detail['execution_error']['node_id'] == '5' + assert job_detail['execution_error']['node_type'] == 'KSampler' def test_include_outputs(self): """When include_outputs=True, should include full output data."""