mmomtchev / swig

This is SWIG JavaScript Evolution, a fork of the SWIG project with modern JavaScript/TypeScript support including WASM and async
http://www.swig.org
Other
11 stars 1 forks source link

When throwing asynchronously the stack trace is not preserved #40

Open mmomtchev opened 6 months ago

mmomtchev commented 6 months ago

When using the recommended method to handle C++ exceptions:

%module napi_stack_traces

// This test works only with NAPI

%include "exception.i"
%exception {
  try {
    $action
  } catch (const std::exception &e) {
    SWIG_Raise(e.what());
    SWIG_fail;
  }
}

%inline %{
  void throws() {
    throw std::logic_error{"error with stack"};
  }
%}
const napi_stack_traces = require('napi_stack_traces');

async function mustBeOnStack2() {
  try {
    await napi_stack_traces.throws();
    console.error('throws() did not throw');
    process.exit(1);
  } catch (e) {
    console.log('error', e, typeof e, e.constructor, e.stack)
    if (!e.stack.match(/mustBeOnStack1/))
      throw new Error('mustBeOnStack1 not on stack');
    if (!e.stack.match(/mustBeOnStack2/))
      throw new Error('mustBeOnStack2 not on stack');
  }
}

function mustBeOnStack1() {
  return mustBeOnStack2();
}

mustBeOnStack1();

The stack trace is not preserved:

error [Error: error with stack] object [Function: Error] { stackTraceLimit: 10 } Error: error with stack
file:///home/mmom/src/swig/Examples/test-suite/javascript/napi_stack_traces_async_runme.mjs:12
      throw new Error('mustBeOnStack1 not on stack');
            ^

Error: mustBeOnStack1 not on stack
    at mustBeOnStack2 (file:///home/mmom/src/swig/Examples/test-suite/javascript/napi_stack_traces_async_runme.mjs:12:13)
mmomtchev commented 6 months ago

Ideally, this should be solved directly in Node-API in napi_create_promise and napi_reject_deferred, but alas, given the ongoing affair, I am still blocked from doing anything in Node.js