Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::exception not caught #1225

Closed
froody opened this issue Oct 25, 2022 · 4 comments
Closed

std::exception not caught #1225

froody opened this issue Oct 25, 2022 · 4 comments

Comments

@froody
Copy link

froody commented Oct 25, 2022

The documentation states "On return from a native method, node-addon-api will automatically convert a pending C++ exception to a JavaScript exception." but in InstanceMethodCallbackWrapper when I call a C++ API that throws std::exception, std::terminate is called because no exception handler is installed. If I wrap my call in something like

try {
   my_api();
} catch (const std::exception &e) {
  Napi::Error::New(info.Env(), e.what()).ThrowAsJavaScriptException();
}

Then the exceptions are passed up to javascript, but based on my reading of the documentation I shouldn't need to do this.

@mhdawson
Copy link
Member

Do you have a simple recreate that we can turn into a test ?

@NickNaso
Copy link
Member

NickNaso commented Nov 3, 2022

Hi @froody,

you're right only the exception of type Napi::Errorare autimatically converted to a JavaScript exception.

#include <napi.h>


Napi::Value MethodCppExcpetion(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  throw std::invalid_argument("Cpp exception.");
  return env.Undefined();
}

Napi::Value MethodNapiExcpetion(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  throw Napi::Error::New(env, "Napi exception");
  return env.Undefined();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports["MethodCppExcpetion"] = Napi::Function::New(env, MethodCppExcpetion);
  exports["MethodNapiExcpetion"] = Napi::Function::New(env, MethodNapiExcpetion);
  return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

If you call MethodCppExcpetion from your JavaScript code:

'use strict'

const addon = require('bindings')('addon')

addon.MethodCppExcpetion()

you will get something like this:

libc++abi: terminating with uncaught exception of type std::invalid_argument
zsh: abort      node index.js

If you call MethodNapiExcpetion from your JavaScript code:

'use strict'

const addon = require('bindings')('addon')

console.log(addon.MethodNapiExcpetion())

you will get something like this:

addon.MethodNapiExcpetion()
      ^

Error: Napi exception
    at Object.<anonymous> (/Users/nicoladelgobbo/Downloads/addon/index.js:6:7)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:82:12)
    at node:internal/main/run_main_module:23:47

Node.js v19.0.0

We had some discusssion about this in the past in this issue #601. The proble is the we don't know what you want to do when a C++ exception will thrown and for now we leaved this respnsibility to the developer bucause we were unsure that trasform a Cpp exception could be the best option.

At least the documentation should be changed, do you want to make a PR?

@mhdawson
Copy link
Member

Discussed in the Node-API team meeting today and @NickNaso is going to update the docs to make it clearer.

@NickNaso
Copy link
Member

I'm closing we updated the documentation through this PR #1241.

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

No branches or pull requests

3 participants