Skip to content

Commit 48f1a69

Browse files
authored
feat: port test_error to CTS (#40)
ports [https://github.com/nodejs/node/tree/main/test/js-native-api/test_error](test_error) Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com>
1 parent 86d68d3 commit 48f1a69

5 files changed

Lines changed: 359 additions & 1 deletion

File tree

PORTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Tests covering the engine-specific part of Node-API, defined in `js_native_api.h
5454
| `test_conversions` | Not ported | Medium |
5555
| `test_dataview` | Not ported | Medium |
5656
| `test_date` | Ported ✅ | Easy |
57-
| `test_error` | Not ported | Medium |
57+
| `test_error` | Ported ✅ | Medium |
5858
| `test_exception` | Not ported | Medium |
5959
| `test_finalizer` | Not ported | Medium |
6060
| `test_function` | Not ported | Medium |

tests/harness/assert.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ if (typeof assert.throws !== 'function') {
7878
}
7979
assert.throws(() => { throw new Error('oops'); }, /oops/);
8080
assert.throws(() => { throw new TypeError('bad'); }, TypeError);
81+
assert.throws(
82+
() => { const err = new Error('match me'); err.code = 'ERR_TEST'; throw err; },
83+
{ code: 'ERR_TEST', message: 'match me' },
84+
);
85+
assert.throws(
86+
() => { throw new RangeError('validate me'); },
87+
(err) => err instanceof RangeError && err.message === 'validate me',
88+
);
8189
threw = false;
8290
try { assert.throws(() => { /* does not throw */ }); } catch { threw = true; }
8391
if (!threw) throw new Error('assert.throws must throw when fn does not throw');
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_node_api_cts_addon(test_error test_error.c)
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
"use strict";
2+
3+
const test_error = loadAddon("test_error");
4+
const theError = new Error("Some error");
5+
const theTypeError = new TypeError("Some type error");
6+
const theSyntaxError = new SyntaxError("Some syntax error");
7+
const theRangeError = new RangeError("Some type error");
8+
const theReferenceError = new ReferenceError("Some reference error");
9+
const theURIError = new URIError("Some URI error");
10+
const theEvalError = new EvalError("Some eval error");
11+
12+
class MyError extends Error {}
13+
const myError = new MyError("Some MyError");
14+
15+
// Test that native error object is correctly classed
16+
assert.strictEqual(test_error.checkError(theError), true);
17+
18+
// Test that native type error object is correctly classed
19+
assert.strictEqual(test_error.checkError(theTypeError), true);
20+
21+
// Test that native syntax error object is correctly classed
22+
assert.strictEqual(test_error.checkError(theSyntaxError), true);
23+
24+
// Test that native range error object is correctly classed
25+
assert.strictEqual(test_error.checkError(theRangeError), true);
26+
27+
// Test that native reference error object is correctly classed
28+
assert.strictEqual(test_error.checkError(theReferenceError), true);
29+
30+
// Test that native URI error object is correctly classed
31+
assert.strictEqual(test_error.checkError(theURIError), true);
32+
33+
// Test that native eval error object is correctly classed
34+
assert.strictEqual(test_error.checkError(theEvalError), true);
35+
36+
// Test that class derived from native error is correctly classed
37+
assert.strictEqual(test_error.checkError(myError), true);
38+
39+
// Test that non-error object is correctly classed
40+
assert.strictEqual(test_error.checkError({}), false);
41+
42+
// Test that non-error primitive is correctly classed
43+
assert.strictEqual(test_error.checkError("non-object"), false);
44+
45+
assert.throws(() => {
46+
test_error.throwExistingError();
47+
}, /^Error: existing error$/);
48+
49+
assert.throws(() => {
50+
test_error.throwError();
51+
}, /^Error: error$/);
52+
53+
assert.throws(() => {
54+
test_error.throwRangeError();
55+
}, /^RangeError: range error$/);
56+
57+
assert.throws(() => {
58+
test_error.throwTypeError();
59+
}, /^TypeError: type error$/);
60+
61+
assert.throws(() => {
62+
test_error.throwSyntaxError();
63+
}, /^SyntaxError: syntax error$/);
64+
65+
[42, {}, [], Symbol("xyzzy"), true, "ball", undefined, null, NaN].forEach(
66+
(value) =>
67+
assert.throws(
68+
() => test_error.throwArbitrary(value),
69+
(err) => {
70+
assert.strictEqual(err, value);
71+
return true;
72+
},
73+
),
74+
);
75+
76+
assert.throws(() => test_error.throwErrorCode(), {
77+
code: "ERR_TEST_CODE",
78+
message: "Error [error]",
79+
});
80+
81+
assert.throws(() => test_error.throwRangeErrorCode(), {
82+
code: "ERR_TEST_CODE",
83+
message: "RangeError [range error]",
84+
});
85+
86+
assert.throws(() => test_error.throwTypeErrorCode(), {
87+
code: "ERR_TEST_CODE",
88+
message: "TypeError [type error]",
89+
});
90+
91+
assert.throws(() => test_error.throwSyntaxErrorCode(), {
92+
code: "ERR_TEST_CODE",
93+
message: "SyntaxError [syntax error]",
94+
});
95+
96+
let error = test_error.createError();
97+
assert.ok(error instanceof Error, "expected error to be an instance of Error");
98+
assert.strictEqual(error.message, "error");
99+
100+
error = test_error.createRangeError();
101+
assert.ok(
102+
error instanceof RangeError,
103+
"expected error to be an instance of RangeError",
104+
);
105+
assert.strictEqual(error.message, "range error");
106+
107+
error = test_error.createTypeError();
108+
assert.ok(
109+
error instanceof TypeError,
110+
"expected error to be an instance of TypeError",
111+
);
112+
assert.strictEqual(error.message, "type error");
113+
114+
error = test_error.createSyntaxError();
115+
assert.ok(
116+
error instanceof SyntaxError,
117+
"expected error to be an instance of SyntaxError",
118+
);
119+
assert.strictEqual(error.message, "syntax error");
120+
121+
error = test_error.createErrorCode();
122+
assert.ok(error instanceof Error, "expected error to be an instance of Error");
123+
assert.strictEqual(error.code, "ERR_TEST_CODE");
124+
assert.strictEqual(error.message, "Error [error]");
125+
assert.strictEqual(error.name, "Error");
126+
127+
error = test_error.createRangeErrorCode();
128+
assert.ok(
129+
error instanceof RangeError,
130+
"expected error to be an instance of RangeError",
131+
);
132+
assert.strictEqual(error.message, "RangeError [range error]");
133+
assert.strictEqual(error.code, "ERR_TEST_CODE");
134+
assert.strictEqual(error.name, "RangeError");
135+
136+
error = test_error.createTypeErrorCode();
137+
assert.ok(
138+
error instanceof TypeError,
139+
"expected error to be an instance of TypeError",
140+
);
141+
assert.strictEqual(error.message, "TypeError [type error]");
142+
assert.strictEqual(error.code, "ERR_TEST_CODE");
143+
assert.strictEqual(error.name, "TypeError");
144+
145+
error = test_error.createSyntaxErrorCode();
146+
assert.ok(
147+
error instanceof SyntaxError,
148+
"expected error to be an instance of SyntaxError",
149+
);
150+
assert.strictEqual(error.message, "SyntaxError [syntax error]");
151+
assert.strictEqual(error.code, "ERR_TEST_CODE");
152+
assert.strictEqual(error.name, "SyntaxError");
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#define NAPI_VERSION 9
2+
#include <js_native_api.h>
3+
#include "../common.h"
4+
#include "../entry_point.h"
5+
6+
static napi_value checkError(napi_env env, napi_callback_info info) {
7+
size_t argc = 1;
8+
napi_value args[1];
9+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
10+
11+
bool r;
12+
NODE_API_CALL(env, napi_is_error(env, args[0], &r));
13+
14+
napi_value result;
15+
NODE_API_CALL(env, napi_get_boolean(env, r, &result));
16+
17+
return result;
18+
}
19+
20+
static napi_value throwExistingError(napi_env env, napi_callback_info info) {
21+
napi_value message;
22+
napi_value error;
23+
NODE_API_CALL(env, napi_create_string_utf8(
24+
env, "existing error", NAPI_AUTO_LENGTH, &message));
25+
NODE_API_CALL(env, napi_create_error(env, NULL, message, &error));
26+
NODE_API_CALL(env, napi_throw(env, error));
27+
return NULL;
28+
}
29+
30+
static napi_value throwError(napi_env env, napi_callback_info info) {
31+
NODE_API_CALL(env, napi_throw_error(env, NULL, "error"));
32+
return NULL;
33+
}
34+
35+
static napi_value throwRangeError(napi_env env, napi_callback_info info) {
36+
NODE_API_CALL(env, napi_throw_range_error(env, NULL, "range error"));
37+
return NULL;
38+
}
39+
40+
static napi_value throwTypeError(napi_env env, napi_callback_info info) {
41+
NODE_API_CALL(env, napi_throw_type_error(env, NULL, "type error"));
42+
return NULL;
43+
}
44+
45+
static napi_value throwSyntaxError(napi_env env, napi_callback_info info) {
46+
NODE_API_CALL(env, node_api_throw_syntax_error(env, NULL, "syntax error"));
47+
return NULL;
48+
}
49+
50+
static napi_value throwErrorCode(napi_env env, napi_callback_info info) {
51+
NODE_API_CALL(env, napi_throw_error(env, "ERR_TEST_CODE", "Error [error]"));
52+
return NULL;
53+
}
54+
55+
static napi_value throwRangeErrorCode(napi_env env, napi_callback_info info) {
56+
NODE_API_CALL(env,
57+
napi_throw_range_error(env, "ERR_TEST_CODE", "RangeError [range error]"));
58+
return NULL;
59+
}
60+
61+
static napi_value throwTypeErrorCode(napi_env env, napi_callback_info info) {
62+
NODE_API_CALL(env,
63+
napi_throw_type_error(env, "ERR_TEST_CODE", "TypeError [type error]"));
64+
return NULL;
65+
}
66+
67+
static napi_value throwSyntaxErrorCode(napi_env env, napi_callback_info info) {
68+
NODE_API_CALL(env,
69+
node_api_throw_syntax_error(env, "ERR_TEST_CODE", "SyntaxError [syntax error]"));
70+
return NULL;
71+
}
72+
73+
static napi_value createError(napi_env env, napi_callback_info info) {
74+
napi_value result;
75+
napi_value message;
76+
NODE_API_CALL(env, napi_create_string_utf8(
77+
env, "error", NAPI_AUTO_LENGTH, &message));
78+
NODE_API_CALL(env, napi_create_error(env, NULL, message, &result));
79+
return result;
80+
}
81+
82+
static napi_value createRangeError(napi_env env, napi_callback_info info) {
83+
napi_value result;
84+
napi_value message;
85+
NODE_API_CALL(env, napi_create_string_utf8(
86+
env, "range error", NAPI_AUTO_LENGTH, &message));
87+
NODE_API_CALL(env, napi_create_range_error(env, NULL, message, &result));
88+
return result;
89+
}
90+
91+
static napi_value createTypeError(napi_env env, napi_callback_info info) {
92+
napi_value result;
93+
napi_value message;
94+
NODE_API_CALL(env, napi_create_string_utf8(
95+
env, "type error", NAPI_AUTO_LENGTH, &message));
96+
NODE_API_CALL(env, napi_create_type_error(env, NULL, message, &result));
97+
return result;
98+
}
99+
100+
static napi_value createSyntaxError(napi_env env, napi_callback_info info) {
101+
napi_value result;
102+
napi_value message;
103+
NODE_API_CALL(env, napi_create_string_utf8(
104+
env, "syntax error", NAPI_AUTO_LENGTH, &message));
105+
NODE_API_CALL(env, node_api_create_syntax_error(env, NULL, message, &result));
106+
return result;
107+
}
108+
109+
static napi_value createErrorCode(napi_env env, napi_callback_info info) {
110+
napi_value result;
111+
napi_value message;
112+
napi_value code;
113+
NODE_API_CALL(env, napi_create_string_utf8(
114+
env, "Error [error]", NAPI_AUTO_LENGTH, &message));
115+
NODE_API_CALL(env, napi_create_string_utf8(
116+
env, "ERR_TEST_CODE", NAPI_AUTO_LENGTH, &code));
117+
NODE_API_CALL(env, napi_create_error(env, code, message, &result));
118+
return result;
119+
}
120+
121+
static napi_value createRangeErrorCode(napi_env env, napi_callback_info info) {
122+
napi_value result;
123+
napi_value message;
124+
napi_value code;
125+
NODE_API_CALL(env,
126+
napi_create_string_utf8(
127+
env, "RangeError [range error]", NAPI_AUTO_LENGTH, &message));
128+
NODE_API_CALL(env, napi_create_string_utf8(
129+
env, "ERR_TEST_CODE", NAPI_AUTO_LENGTH, &code));
130+
NODE_API_CALL(env, napi_create_range_error(env, code, message, &result));
131+
return result;
132+
}
133+
134+
static napi_value createTypeErrorCode(napi_env env, napi_callback_info info) {
135+
napi_value result;
136+
napi_value message;
137+
napi_value code;
138+
NODE_API_CALL(env,
139+
napi_create_string_utf8(
140+
env, "TypeError [type error]", NAPI_AUTO_LENGTH, &message));
141+
NODE_API_CALL(env, napi_create_string_utf8(
142+
env, "ERR_TEST_CODE", NAPI_AUTO_LENGTH, &code));
143+
NODE_API_CALL(env, napi_create_type_error(env, code, message, &result));
144+
return result;
145+
}
146+
147+
static napi_value createSyntaxErrorCode(napi_env env, napi_callback_info info) {
148+
napi_value result;
149+
napi_value message;
150+
napi_value code;
151+
NODE_API_CALL(env,
152+
napi_create_string_utf8(
153+
env, "SyntaxError [syntax error]", NAPI_AUTO_LENGTH, &message));
154+
NODE_API_CALL(env, napi_create_string_utf8(
155+
env, "ERR_TEST_CODE", NAPI_AUTO_LENGTH, &code));
156+
NODE_API_CALL(env, node_api_create_syntax_error(env, code, message, &result));
157+
return result;
158+
}
159+
160+
static napi_value throwArbitrary(napi_env env, napi_callback_info info) {
161+
napi_value arbitrary;
162+
size_t argc = 1;
163+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, &arbitrary, NULL, NULL));
164+
NODE_API_CALL(env, napi_throw(env, arbitrary));
165+
return NULL;
166+
}
167+
168+
EXTERN_C_START
169+
napi_value Init(napi_env env, napi_value exports) {
170+
napi_property_descriptor descriptors[] = {
171+
DECLARE_NODE_API_PROPERTY("checkError", checkError),
172+
DECLARE_NODE_API_PROPERTY("throwExistingError", throwExistingError),
173+
DECLARE_NODE_API_PROPERTY("throwError", throwError),
174+
DECLARE_NODE_API_PROPERTY("throwRangeError", throwRangeError),
175+
DECLARE_NODE_API_PROPERTY("throwTypeError", throwTypeError),
176+
DECLARE_NODE_API_PROPERTY("throwSyntaxError", throwSyntaxError),
177+
DECLARE_NODE_API_PROPERTY("throwErrorCode", throwErrorCode),
178+
DECLARE_NODE_API_PROPERTY("throwRangeErrorCode", throwRangeErrorCode),
179+
DECLARE_NODE_API_PROPERTY("throwTypeErrorCode", throwTypeErrorCode),
180+
DECLARE_NODE_API_PROPERTY("throwSyntaxErrorCode", throwSyntaxErrorCode),
181+
DECLARE_NODE_API_PROPERTY("throwArbitrary", throwArbitrary),
182+
DECLARE_NODE_API_PROPERTY("createError", createError),
183+
DECLARE_NODE_API_PROPERTY("createRangeError", createRangeError),
184+
DECLARE_NODE_API_PROPERTY("createTypeError", createTypeError),
185+
DECLARE_NODE_API_PROPERTY("createSyntaxError", createSyntaxError),
186+
DECLARE_NODE_API_PROPERTY("createErrorCode", createErrorCode),
187+
DECLARE_NODE_API_PROPERTY("createRangeErrorCode", createRangeErrorCode),
188+
DECLARE_NODE_API_PROPERTY("createTypeErrorCode", createTypeErrorCode),
189+
DECLARE_NODE_API_PROPERTY("createSyntaxErrorCode", createSyntaxErrorCode),
190+
};
191+
192+
NODE_API_CALL(env, napi_define_properties(
193+
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
194+
195+
return exports;
196+
}
197+
EXTERN_C_END

0 commit comments

Comments
 (0)