Skip to content

Fix unhandled promise rejections in workflow error handling#1

Merged
igorls merged 5 commits intomainfrom
copilot/handle-errors-in-comfyui-library
Oct 29, 2025
Merged

Fix unhandled promise rejections in workflow error handling#1
igorls merged 5 commits intomainfrom
copilot/handle-errors-in-comfyui-library

Conversation

Copy link
Contributor

Copilot AI commented Oct 29, 2025

When workflow enqueue operations fail, unhandled promise rejections crash the process. This violates the design goal of providing a robust library for server-side usage that gracefully handles all errors.

Changes

workflow.ts

  • Added .catch() handler to exec() invocation when not using a pool (line 417) - the async function was previously called without error handling
  • Added no-op .catch() to donePromise on creation (line 63) - prevents runtime from detecting unhandled rejection when promise is rejected before user code awaits done()

test/enqueue-failures.spec.ts

  • Added tests verifying workflow.run() handles enqueue failures without process crashes
  • Tests confirm errors propagate correctly through promise chain and failed events are emitted

Example

Before this fix, the following would crash the process:

const client = new ComfyApi("http://localhost:8188");
const wf = Workflow.from(workflowJSON);

try {
  const job = await client.run(wf);
  const result = await job.done();
} catch (err) {
  // Error would crash process before reaching here
  console.error("Handled:", err);
}

After the fix, errors are properly caught and the process remains stable.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • x
    • Triggering command: bun test (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

this issue cannot happen, when the library is used via WorkflowPool no errors should crash it, they must be gracefully handled, our goal is to design a robust comfyui library for server-side usage, that by default is able to handle adverse scenarios without crashes

bun run scripts/two-stage-edit-simulation.ts
[2025-10-29T16:16:21.145Z] Two-stage edit simulation starting {
  hosts: [ "http://localhost:8188", "http://afterpic-comfy-aero16:8188", "http://afterpic-comfy-domi:8188" ],
  runtimeHours: 6,
  minDelayMs: 30000,
  maxDelayMs: 240000,
  seedStrategy: "random",
}
[2025-10-29T16:16:22.250Z] Starting first cycle immediately
[2025-10-29T16:16:22.250Z] ▶️  [http://afterpic-comfy-domi:8188] Generation run #1 seed=1753525260
[debug] emitFailure start EnqueueFailedError
[debug] emitFailure end EnqueueFailedError
[2025-10-29T16:16:22.260Z] ⚠️  Marking http://afterpic-comfy-domi:8188 as generation-incapable (Failed to queue prompt)
[2025-10-29T16:16:22.260Z] Starting first cycle immediately
[2025-10-29T16:16:22.260Z] ▶️  [http://localhost:8188] Generation run #1 seed=1544804889
42 |   } else {
43 |     bodyTextSnippet = JSON.stringify(bodyJSON).slice(0, 500);
44 |   }
45 |
46 |   const reason = extractReason(bodyJSON) || bodyTextSnippet;
47 |   return new EnqueueFailedError("Failed to queue prompt", {
              ^
EnqueueFailedError: Failed to queue prompt
     status: 400,
 statusText: "Bad Request",
        url: "http://afterpic-comfy-domi:8188/prompt",
     method: undefined,
   bodyJSON: {
  error: [Object ...],
  node_errors: [Object ...],
},
 bodyTextSnippet: "{\"error\":{\"type\":\"prompt_outputs_failed_validation\",\"message\":\"Prompt outputs failed validation\",\"details\":\"\",\"extra_info\"
:{}},\"node_errors\":{\"6\":{\"errors\":[{\"type\":\"value_not_in_list\",\"message\":\"Value not in list\",\"details\":\"ckpt_name: 'novaAnimeXL_ilV125.safetensors' not in []\",\"extra_info\":{\"input_name\":\"ckpt_name\",\"input_config\":[[],{\"tooltip\":\"The name of the checkpoint (model) to load.\"}],\"received_value\":\"novaAnimeXL_ilV125.safetensors\"}}],\"dependent_outputs\":[\"12\"],\"class_type\":\"Checkpoi",                                                       reason: "{\"error\":{\"type\":\"prompt_outputs_failed_validation\",\"message\":\"Prompt outputs failed validation\",\"details\":\"\",\"extra_info\":{}},
\"node_errors\":{\"6\":{\"errors\":[{\"type\":\"value_not_in_list\",\"message\":\"Value not in list\",\"details\":\"ckpt_name: 'novaAnimeXL_ilV125.safetensors' not in []\",\"extra_info\":{\"input_name\":\"ckpt_name\",\"input_config\":[[],{\"tooltip\":\"The name of the checkpoint (model) to load.\"}],\"received_value\":\"novaAnimeXL_ilV125.safetensors\"}}],\"dependent_outputs\":[\"12\"],\"class_type\":\"Checkpoi",                                                              code: "E_ENQUEUE_FAILED"

      at buildEnqueueFailedError (D:\GitHub\comfyui-node\src\utils\response-error.ts:47:10)
      at async queuePrompt (D:\GitHub\comfyui-node\src\features\queue.ts:49:25)
      at async appendPrompt (D:\GitHub\comfyui-node\src\features\queue.ts:60:25)
      at async enqueueJob (D:\GitHub\comfyui-node\src\call-wrapper.ts:456:41)
      at async run (D:\GitHub\comfyui-node\src\call-wrapper.ts:203:28)
      at async <anonymous> (D:\GitHub\comfyui-node\src\workflow.ts:409:31)

Bun v1.3.2-canary.34+6580b563b (Windows x64)

Created from VS Code via the GitHub Pull Request extension.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits October 29, 2025 16:22
Co-authored-by: igorls <4753812+igorls@users.noreply.github.com>
- Add .catch() handler to exec() when not using pool to prevent unhandled rejections
- Add .catch() handler to donePromise to prevent unhandled rejection warnings
- Add tests to verify error handling works correctly without crashing

Co-authored-by: igorls <4753812+igorls@users.noreply.github.com>
Co-authored-by: igorls <4753812+igorls@users.noreply.github.com>
Co-authored-by: igorls <4753812+igorls@users.noreply.github.com>
Copilot AI changed the title [WIP] Add error handling for WorkflowPool scenarios Fix unhandled promise rejections in workflow error handling Oct 29, 2025
Copilot AI requested a review from igorls October 29, 2025 16:35
@igorls igorls marked this pull request as ready for review October 29, 2025 20:57
Copilot AI review requested due to automatic review settings October 29, 2025 20:57
@igorls igorls merged commit 405b78b into main Oct 29, 2025
@igorls igorls deleted the copilot/handle-errors-in-comfyui-library branch October 29, 2025 20:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes unhandled promise rejection warnings that occur during workflow enqueue failures when no pool is used. The fix ensures that promise rejections in the exec() function are properly caught and handled by attaching error handlers.

Key changes:

  • Added .catch() handler to exec() call when no pool is used
  • Added a no-op catch handler to donePromise in WorkflowJob constructor to prevent unhandled rejection warnings
  • Added comprehensive tests for enqueue failure scenarios without pool

Reviewed Changes

Copilot reviewed 2 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/workflow.ts Added .catch() handler to exec() when no pool is used; added no-op catch to donePromise to suppress warnings
test/enqueue-failures.spec.ts Added two new test cases covering enqueue failures without pool
dist/workflow.js Compiled JavaScript output reflecting the source changes
dist/workflow.js.map Updated source map for compiled JavaScript
dist/workflow.d.ts.map Updated TypeScript declaration source map
bun.lock Updated @types/bun dependency version

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

try {
await wf.run(api as any);
// If we reach here, the test should fail because run() should have thrown
expect(true).toBe(false); // Force test failure if no error was thrown
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using expect(true).toBe(false) to force a test failure, use expect.fail() or simply omit this line—the test will naturally fail if no exception is thrown since the catch block won't be entered. Alternatively, restructure with await expect(wf.run(api as any)).rejects.toBeInstanceOf(EnqueueFailedError) for more idiomatic testing of async rejections.

Suggested change
expect(true).toBe(false); // Force test failure if no error was thrown
expect.fail(); // Force test failure if no error was thrown

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants