Skip to content

Throw within queueMicrotask callbacks should not crash Node #38145

Description

@Huxpro
  • Version:v15.9.0
  • Platform: macOS x86
  • Subsystem: task_queues

What steps will reproduce the bug?

λ node --trace-uncaught
Welcome to Node.js v15.9.0.
Type ".help" for more information.
> queueMicrotask(_ => { throw 1 });
undefined
>
node:internal/process/task_queues:94
    runMicrotasks();
    ^
1
Thrown at:
    at processTicksAndRejections (node:internal/process/task_queues:94:5)

How often does it reproduce? Is there a required condition?

Always.

What is the expected behavior?

If I understood the spec correct:

The queueMicrotask(callback) method must queue a microtask to invoke callback, and if callback throws an exception, report the exception.

It should behave similarly as Timer tasks.

> setTimeout(_ => {throw 1});
Timeout {
  ...
}
> Uncaught 1

What do you see instead?

Node crashed

Additional information

I did some preliminary triages that hopefully helps a bit:

  • task_queues.js invoke runMicrotask
  • which is a JS binding from node_task_queue.cc which invokes V8's PerformCheckpoint under the hood.
  • V8's PerformCheckpoint invoked V8's RunMicrotasks to actually evaluate those JS callbacks.

But since V8's PerformCheckpoint returns void. I'm not sure how can Node be aware of any exceptions threw during the evaluation of those JS callbacks. Chromium seems to handle this fine but I haven't got time looking at its source.

Activity

  1. changed the title [-]Throw in the queueMicrotask callbacks[/-] [+]Throw within queueMicrotask callbacks should not crash Node[/+] on Apr 8, 2021
  2. added
    processIssues and PRs related to the process subsystem.
    on Apr 8, 2021
  3. devsnek commented on Apr 8, 2021

    @devsnek
    Member

    The exception is reported via the uncaughtException event. If nothing handles that, the exception is fatal, like all other uncaught exceptions.

  4. Huxpro commented on Apr 8, 2021

    @Huxpro
    Author

    @devsnek ah that make sense.

    Out of line question: there isn't an equivalent API on the Web that can do what process.on('uncaughtException', ..) on Node, right?

  5. legendecas commented on Apr 8, 2021

    @legendecas
    Member

    @Huxpro: there isn't an equivalent API on the Web that can do what process.on('uncaughtException', ..) on Node, right?

    If you mean to monitor those uncaught exceptions, try window.addEventListener('error', ...) (and unhandledrejection for unhandledRejection in Node.js respectively).

  6. Huxpro commented on Apr 8, 2021

    @Huxpro
    Author

    @devsnek although it's spec-conformant in that sense. Why wouldn't queueMicrotask behave the same as setTimeout?

  7. targos commented on Apr 11, 2021

    @targos
    Member

    I'm reopening because it seems worth fixing (if possible) in the REPL.

  8. reopened this on Apr 11, 2021
  9. added
    replIssues and PRs related to the REPL subsystem.
    on Apr 11, 2021
  10. Linkgoron commented on Apr 12, 2021

    @Linkgoron
    Contributor

    I'm reopening because it seems worth fixing (if possible) in the REPL.

    This actually works in the REPL of Node 12 and 14.4 but stopped working in Node 14.5. I think that the issue is that errors thrown in queueMicroTask don't get captured by the domain, and don't reach the domain error handler (in the repl). The behaviour change was probably caused by this change #33859

  11. EladKeyshawn commented on Apr 12, 2021

    @EladKeyshawn

    @Linkgoron Does it still need fixing?

  12. BridgeAR commented on Nov 29, 2021

    @BridgeAR
    Member

    @EladKeyshawn yes, it does.

    The question is how something like that might be solved. One way would be to use child processes to execute the code and to detect fatal exceptions leading to a new child process. However, that would only recover the REPL but all former input would be lost. Thus, we would have to print a clear warning about what happened. This is the best solution I can think of and it would also resolve multiple other reports.

  13. jasnell commented on Jan 22, 2025

    @jasnell
    Member

    There's been no further discussion or activity on this in years. Is this still relevant? Still an issue? Is it something that just needs to be documented better?

  14. added a commit that references this issue on Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues and PRs for confirmed bugs.processIssues and PRs related to the process subsystem.replIssues and PRs related to the REPL subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions