Skip to content

fix(void): log queue handler errors instead of dropping them - #629

Open
morinokami wants to merge 3 commits into
voidzero-dev:mainfrom
morinokami:fix/log-queue-handler-errors
Open

morinokami wants to merge 3 commits into
voidzero-dev:mainfrom
morinokami:fix/log-queue-handler-errors

Conversation

@morinokami

Copy link
Copy Markdown

Summary

When a queue handler throws, its error is never logged. The generated __processQueue catches it without binding it (} catch { __ok = false; }), so the reason is lost on every path:

  • Native Cloudflare consumers: the Worker's queue() throws a new Error("queue: Handler failed."), and Workers Logs and void project logs show only that.
  • Dev: /__void/queue answers {"ok":false}, and nothing reaches the terminal.
  • Void Cloud: the relay gets a 200 {"ok":false} and retries the batch, and nothing is logged.

The generated scheduled() already logs a failing job's error ([void] Scheduled job … failed for cron "…"). __processQueue in packages/void/src/router/compile.ts now does the same for queue handlers before marking the batch failed, which covers all three paths. When no handler matches the queue, __processQueue returned the reason only as error, which the native queue() dropped and the Void Cloud relay ignores, so it now logs that reason too. handleQueueRelay in packages/void/src/cli/wrapper.ts had the same catch and now logs too. The wrapper's native queue() already lets errors through, and the framework dev trigger already logs them ([void] queue handler threw:).

The thrown queue: Handler failed., the { ok: false } result and the ack/retry decisions are unchanged. docs/guide/queues.md now says the handler's error is logged.

Repro

  1. queues/fail.ts:
    import { defineQueue } from 'void';
    
    export default defineQueue(async () => {
      throw new Error('boom');
    });
  2. Start the dev server, then send it a message with the token it prints:
    curl -X POST http://localhost:5173/__void/queue \
      -H "x-void-dev-trigger: <token>" \
      -d '{"queue":"fail","messages":[{"id":"1","timestamp":0,"body":{},"attempts":1}]}'
  • Before: the response is {"ok":false}, and boom is logged nowhere.
  • After: the response is unchanged, and the terminal shows [void] Queue handler queues/fail.ts failed for queue "fail": Error: boom with its stack. A message sent through the queue binding (Miniflare's native delivery) logs the same line.

Tests

  • packages/void/test/integration/queue-dispatch.test.ts: the error a handler throws reaches console.error as the same object, with its file and queue, through __processQueue and through the native queue(). Both also log the reason for an unknown queue.
  • packages/void/test/unit/wrapper.test.ts: the same for the wrapper's HTTP relay.

morinokami and others added 3 commits October 28, 2026 12:27
The generated __processQueue caught a handler's error without binding it,
so the reason a batch failed was lost: Cloudflare recorded only
"queue: Handler failed.", and the dev server and Void Cloud got
{"ok":false} with nothing logged. Log the error with the handler file
and queue name, as scheduled() does for jobs. The native queue() also
logs why no handler matched a queue, a reason only the HTTP route
passed on. The framework wrapper's HTTP relay logs handler errors too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J8F8mceGgtLyricGiHmQNt
When no handler matched a queue, only the native queue() logged the
reason. The HTTP route returned it as `error`, which the Void Cloud
relay ignores, so a batch for an unknown queue was retried with
nothing logged. Log the reason in __processQueue, where handler errors
are logged, and drop the native queue()'s own log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J8F8mZUqZxveCneED8EgLC

This branch has not been deployed

No deployments
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.

1 participant