Skip to content

async_hooks: async hook stack corruption when exception prevents AsyncResource.emitAfter being called. #16156

@akdor1154

Description

@akdor1154
  • Version: 8.2.1, 8.7
  • Platform:
  • Subsystem: async_hooks

According to async_hooks docs,

If the user's callback throws an exception, emitAfter() will automatically be called for all asyncIds on the stack if the error is handled by a domain or 'uncaughtException' handler.

However, this doesn't seem to work in practice. If I set up a simple AsyncResource to bind a function to its own execution context,

class BoundFunction extends asyncHooks.AsyncResource {
  constructor(f) {
    super('BOUND_FUNCTION');
    this.f = f;
  }

  run() {
    this.emitBefore();
    f();
    this.emitAfter();
  }
}

and use it like

const f = () => {
  throw new Error('uh ho');
};

const boundF = new BoundFunction(f);

process.nextTick( () => {
  try {
    boundF.run();
  } catch (e) {
    console.log('nothing to worry about');
  }
});

Then I get the following output from node:

$ node src/demonstration.js
nothing to worry about
Error: async hook stack has become corrupted (actual: 5, expected: 6)
 1: node::AsyncWrap::PopAsyncIds(v8::FunctionCallbackInfo<v8::Value> const&) [node]
 2: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [node]
 3: 0xb8f43c [node]
 4: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [node]
 5: 0x3aa19890463d

This happens even if I set up handlers for uncaught exceptions and rejections:

process.on('uncaughtException', (e) => { console.log('no worries'); });
process.on('unhandledRejection', (e) => { console.log('relax bro'); });

If I change BoundFunction#run to look like

run() {
  this.emitBefore();
  try {
    f();
  } finally {
    this.emitAfter();
  }
}

the error goes away. I am fine with my handler looking like that, but it's a bit confusing that the docs seem to say that it shouldn't be required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    async_hooksIssues and PRs related to the async hooks subsystem.docIssues and PRs related to the documentations.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions