Skip to content

Commit 3bd18c5

Browse files
kfarnungaddaleax
authored andcommitted
n-api: add napi_fatal_error API
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]>
1 parent 1671fe4 commit 3bd18c5

File tree

6 files changed

+75
-0
lines changed

6 files changed

+75
-0
lines changed

doc/api/n-api.md

+17
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,23 @@ Returns `napi_ok` if the API succeeded.
490490
491491
This API returns true if an exception is pending.
492492
493+
### Fatal Errors
494+
495+
In the event of an unrecoverable error in a native module, a fatal error can be
496+
thrown to immediately terminate the process.
497+
498+
#### napi_fatal_error
499+
<!-- YAML
500+
added: REPLACEME
501+
-->
502+
```C
503+
NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location, const char* message);
504+
```
505+
506+
- `[in] location`: Optional location at which the error occurred.
507+
- `[in] message`: The message associated with the error.
508+
509+
The function call does not return, the process will be terminated.
493510

494511
## Object Lifetime management
495512

src/node_api.cc

+5
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@ napi_status napi_get_last_error_info(napi_env env,
822822
return napi_ok;
823823
}
824824

825+
NAPI_NO_RETURN void napi_fatal_error(const char* location,
826+
const char* message) {
827+
node::FatalError(location, message);
828+
}
829+
825830
napi_status napi_create_function(napi_env env,
826831
const char* utf8name,
827832
napi_callback cb,

src/node_api.h

+9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
# define NAPI_MODULE_EXPORT __attribute__((visibility("default")))
3838
#endif
3939

40+
#ifdef __GNUC__
41+
#define NAPI_NO_RETURN __attribute__((noreturn))
42+
#else
43+
#define NAPI_NO_RETURN
44+
#endif
45+
4046

4147
typedef void (*napi_addon_register_func)(napi_env env,
4248
napi_value exports,
@@ -104,6 +110,9 @@ NAPI_EXTERN napi_status
104110
napi_get_last_error_info(napi_env env,
105111
const napi_extended_error_info** result);
106112

113+
NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
114+
const char* message);
115+
107116
// Getters for defined singletons
108117
NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result);
109118
NAPI_EXTERN napi_status napi_get_null(napi_env env, napi_value* result);
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"targets": [
3+
{
4+
"target_name": "test_fatal",
5+
"sources": [ "test_fatal.c" ]
6+
}
7+
]
8+
}

test/addons-napi/test_fatal/test.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
const common = require('../../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
const test_fatal = require(`./build/${common.buildType}/test_fatal`);
6+
7+
// Test in a child process because the test code will trigger a fatal error
8+
// that crashes the process.
9+
if (process.argv[2] === 'child') {
10+
test_fatal.Test();
11+
return;
12+
}
13+
14+
const p = child_process.spawnSync(
15+
process.execPath, [ '--napi-modules', __filename, 'child' ]);
16+
assert.ifError(p.error);
17+
assert.ok(p.stderr.toString().includes(
18+
'FATAL ERROR: test_fatal::Test fatal message'));
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <node_api.h>
2+
#include "../common.h"
3+
4+
napi_value Test(napi_env env, napi_callback_info info) {
5+
napi_fatal_error("test_fatal::Test", "fatal message");
6+
return NULL;
7+
}
8+
9+
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
10+
napi_property_descriptor properties[] = {
11+
DECLARE_NAPI_PROPERTY("Test", Test),
12+
};
13+
14+
NAPI_CALL_RETURN_VOID(env, napi_define_properties(
15+
env, exports, sizeof(properties) / sizeof(*properties), properties));
16+
}
17+
18+
NAPI_MODULE(addon, Init)

0 commit comments

Comments
 (0)