Skip to content

Commit

Permalink
n-api: add napi_fatal_error API
Browse files Browse the repository at this point in the history
PR-URL: #13971
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jason Ginchereau <[email protected]>
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
  • Loading branch information
kfarnung authored and mhdawson committed Jul 13, 2017
1 parent a74ddff commit 73078d6
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 0 deletions.
17 changes: 17 additions & 0 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,23 @@ Returns `napi_ok` if the API succeeded.
This API returns true if an exception is pending.
### Fatal Errors
In the event of an unrecoverable error in a native module, a fatal error can be
thrown to immediately terminate the process.
#### napi_fatal_error
<!-- YAML
added: REPLACEME
-->
```C
NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location, const char* message);
```

- `[in] location`: Optional location at which the error occurred.
- `[in] message`: The message associated with the error.

The function call does not return, the process will be terminated.

## Object Lifetime management

Expand Down
5 changes: 5 additions & 0 deletions src/node_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,11 @@ napi_status napi_get_last_error_info(napi_env env,
return napi_ok;
}

NAPI_NO_RETURN void napi_fatal_error(const char* location,
const char* message) {
node::FatalError(location, message);
}

napi_status napi_create_function(napi_env env,
const char* utf8name,
napi_callback cb,
Expand Down
9 changes: 9 additions & 0 deletions src/node_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
# define NAPI_MODULE_EXPORT __attribute__((visibility("default")))
#endif

#ifdef __GNUC__
#define NAPI_NO_RETURN __attribute__((noreturn))
#else
#define NAPI_NO_RETURN
#endif


typedef void (*napi_addon_register_func)(napi_env env,
napi_value exports,
Expand Down Expand Up @@ -104,6 +110,9 @@ NAPI_EXTERN napi_status
napi_get_last_error_info(napi_env env,
const napi_extended_error_info** result);

NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
const char* message);

// Getters for defined singletons
NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result);
NAPI_EXTERN napi_status napi_get_null(napi_env env, napi_value* result);
Expand Down
8 changes: 8 additions & 0 deletions test/addons-napi/test_fatal/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"targets": [
{
"target_name": "test_fatal",
"sources": [ "test_fatal.c" ]
}
]
}
18 changes: 18 additions & 0 deletions test/addons-napi/test_fatal/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
const common = require('../../common');
const assert = require('assert');
const child_process = require('child_process');
const test_fatal = require(`./build/${common.buildType}/test_fatal`);

// Test in a child process because the test code will trigger a fatal error
// that crashes the process.

This comment has been minimized.

Copy link
@vijayattri27

vijayattri27 Jul 24, 2017

process.argv.length === 3

This comment has been minimized.

Copy link
@cjihrig

cjihrig Jul 24, 2017

Contributor

Yes. process.argv[2] is 'child' though.

if (process.argv[2] === 'child') {
test_fatal.Test();
return;
}

const p = child_process.spawnSync(
process.execPath, [ '--napi-modules', __filename, 'child' ]);
assert.ifError(p.error);
assert.ok(p.stderr.toString().includes(
'FATAL ERROR: test_fatal::Test fatal message'));
18 changes: 18 additions & 0 deletions test/addons-napi/test_fatal/test_fatal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <node_api.h>
#include "../common.h"

napi_value Test(napi_env env, napi_callback_info info) {
napi_fatal_error("test_fatal::Test", "fatal message");
return NULL;
}

void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
napi_property_descriptor properties[] = {
DECLARE_NAPI_PROPERTY("Test", Test),
};

NAPI_CALL_RETURN_VOID(env, napi_define_properties(
env, exports, sizeof(properties) / sizeof(*properties), properties));
}

NAPI_MODULE(addon, Init)

1 comment on commit 73078d6

@cjihrig
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the metadata for this commit should have included:

Fixes: #13927

Please sign in to comment.