Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
n-api: add napi_fatal_exception
  • Loading branch information
mafintosh committed Mar 14, 2018
commit a575495353c82a11df978151facfdf9df719027c
13 changes: 13 additions & 0 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,19 @@ This API returns true if an exception is pending.

This API can be called even if there is a pending JavaScript exception.

#### napi_fatal_exception
<!-- YAML
added: TBA
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REPLACEME is the magic word that gets picked up by the release tooling, please change to that :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! i was offline and trying hard to remember what it was

-->
```C
napi_fatal_exception(napi_env env);
```

- `[in] env`: The environment that the API is invoked under.

Trigger an `uncaughtException` in JavaScript. Useful if an async
callback throws an exception with no way to recover.

### Fatal Errors

In the event of an unrecoverable error in a native module, a fatal error can be
Expand Down
18 changes: 11 additions & 7 deletions src/node_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,16 @@ napi_status napi_get_last_error_info(napi_env env,
return napi_ok;
}

void napi_fatal_exception(napi_env env) {
if (!env->last_exception.IsEmpty()) {
v8::Local<v8::Value> err = v8::Local<v8::Value>::New(
env->isolate, env->last_exception);
v8::Local<v8::Message> msg = v8::Exception::CreateMessage(
env->isolate, err);
node::FatalException(env->isolate, err, msg);
}
}

NAPI_NO_RETURN void napi_fatal_error(const char* location,
size_t location_len,
const char* message,
Expand Down Expand Up @@ -3353,13 +3363,7 @@ class Work : public node::AsyncResource {
// If there was an unhandled exception in the complete callback,
// report it as a fatal exception. (There is no JavaScript on the
// callstack that can possibly handle it.)
if (!env->last_exception.IsEmpty()) {
v8::Local<v8::Value> err = v8::Local<v8::Value>::New(
env->isolate, env->last_exception);
v8::Local<v8::Message> msg = v8::Exception::CreateMessage(
env->isolate, err);
node::FatalException(env->isolate, err, msg);
}
napi_fatal_exception(env);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/node_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ NAPI_EXTERN napi_status
napi_get_last_error_info(napi_env env,
const napi_extended_error_info** result);

NAPI_EXTERN void napi_fatal_exception(napi_env env);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would prefer it if you could pass in the exception here, like the existing Node APIs do – you should be able to get a currently pending exception with napi_get_and_clear_last_exception.

Actually passing the exception along to Node’s fatal exception handling seems orthogonal to that?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orthogonal? i'm ok with added a napi_value that is used as the exception yes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mh, sorry – orthogonal ~= independent … basically, I’d suggest that we provide users with the smallest pieces that make sense to be exposed in the API, rather than exposing a function that actually does two operations masquerading as one (getting the last exception + passing it to the fatal exception handler)


NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
size_t location_len,
const char* message,
Expand Down