Skip to content

Commit d9828c6

Browse files
authored
src: add SyntaxError (#1326)
1 parent 717a619 commit d9828c6

File tree

7 files changed

+160
-0
lines changed

7 files changed

+160
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ The following is the documentation for node-addon-api.
132132
- [Error](doc/error.md)
133133
- [TypeError](doc/type_error.md)
134134
- [RangeError](doc/range_error.md)
135+
- [SyntaxError](doc/syntax_error.md)
135136
- [Object Lifetime Management](doc/object_lifetime_management.md)
136137
- [HandleScope](doc/handle_scope.md)
137138
- [EscapableHandleScope](doc/escapable_handle_scope.md)

doc/hierarchy.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
| [`Napi::Reference`] | |
3838
| [`Napi::String`][] | [`Napi::Name`][] |
3939
| [`Napi::Symbol`][] | [`Napi::Name`][] |
40+
| [`Napi::SyntaxError`][] | [`Napi::Error`][] |
4041
| [`Napi::ThreadSafeFunction`][] | |
4142
| [`Napi::TypeTaggable`][] | [`Napi::Value][] |
4243
| [`Napi::TypeError`][] | [`Napi::Error`][] |
@@ -82,6 +83,7 @@
8283
[`Napi::Reference<Napi::Object>`]: ./reference.md
8384
[`Napi::String`]: ./string.md
8485
[`Napi::Symbol`]: ./symbol.md
86+
[`Napi::SyntaxError`]: ./syntax_error.md
8587
[`Napi::ThreadSafeFunction`]: ./threadsafe_function.md
8688
[`Napi::TypeError`]: ./type_error.md
8789
[`Napi::TypeTaggable`]: ./type_taggable.md

doc/syntax_error.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# SyntaxError
2+
3+
The `Napi::SyntaxError` class is a representation of the JavaScript
4+
`SyntaxError` that is thrown when the engine encounters tokens or token order
5+
that does not conform to the syntax of the language when parsing code.
6+
7+
The `Napi::SyntaxError` class inherits its behaviors from the `Napi::Error`
8+
class (for more info see: [`Napi::Error`](error.md)).
9+
10+
For more details about error handling refer to the section titled [Error
11+
handling](error_handling.md).
12+
13+
## Methods
14+
15+
### New
16+
17+
Creates a new instance of a `Napi::SyntaxError` object.
18+
19+
```cpp
20+
Napi::SyntaxError::New(Napi::Env env, const char* message);
21+
```
22+
23+
- `[in] Env`: The environment in which to construct the `Napi::SyntaxError`
24+
object.
25+
- `[in] message`: Null-terminated string to be used as the message for the
26+
`Napi::SyntaxError`.
27+
28+
Returns an instance of a `Napi::SyntaxError` object.
29+
30+
### New
31+
32+
Creates a new instance of a `Napi::SyntaxError` object.
33+
34+
```cpp
35+
Napi::SyntaxError::New(Napi::Env env, const std::string& message);
36+
```
37+
38+
- `[in] Env`: The environment in which to construct the `Napi::SyntaxError`
39+
object.
40+
- `[in] message`: Reference string to be used as the message for the
41+
`Napi::SyntaxError`.
42+
43+
Returns an instance of a `Napi::SyntaxError` object.
44+
45+
### Constructor
46+
47+
Creates a new empty instance of a `Napi::SyntaxError`.
48+
49+
```cpp
50+
Napi::SyntaxError::SyntaxError();
51+
```
52+
53+
### Constructor
54+
55+
Initializes a `Napi::SyntaxError` instance from an existing Javascript error
56+
object.
57+
58+
```cpp
59+
Napi::SyntaxError::SyntaxError(napi_env env, napi_value value);
60+
```
61+
62+
- `[in] Env`: The environment in which to construct the `Napi::SyntaxError`
63+
object.
64+
- `[in] value`: The `Napi::Error` reference to wrap.
65+
66+
Returns an instance of a `Napi::SyntaxError` object.

napi-inl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,6 +3157,23 @@ inline RangeError::RangeError() : Error() {}
31573157
inline RangeError::RangeError(napi_env env, napi_value value)
31583158
: Error(env, value) {}
31593159

3160+
#if NAPI_VERSION > 8
3161+
inline SyntaxError SyntaxError::New(napi_env env, const char* message) {
3162+
return Error::New<SyntaxError>(
3163+
env, message, std::strlen(message), node_api_create_syntax_error);
3164+
}
3165+
3166+
inline SyntaxError SyntaxError::New(napi_env env, const std::string& message) {
3167+
return Error::New<SyntaxError>(
3168+
env, message.c_str(), message.size(), node_api_create_syntax_error);
3169+
}
3170+
3171+
inline SyntaxError::SyntaxError() : Error() {}
3172+
3173+
inline SyntaxError::SyntaxError(napi_env env, napi_value value)
3174+
: Error(env, value) {}
3175+
#endif // NAPI_VERSION > 8
3176+
31603177
////////////////////////////////////////////////////////////////////////////////
31613178
// Reference<T> class
31623179
////////////////////////////////////////////////////////////////////////////////

napi.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,17 @@ class RangeError : public Error {
18531853
RangeError(napi_env env, napi_value value);
18541854
};
18551855

1856+
#if NAPI_VERSION > 8
1857+
class SyntaxError : public Error {
1858+
public:
1859+
static SyntaxError New(napi_env env, const char* message);
1860+
static SyntaxError New(napi_env env, const std::string& message);
1861+
1862+
SyntaxError();
1863+
SyntaxError(napi_env env, napi_value value);
1864+
};
1865+
#endif // NAPI_VERSION > 8
1866+
18561867
class CallbackInfo {
18571868
public:
18581869
CallbackInfo(napi_env env, napi_callback_info info);

test/error.cc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,27 @@ void ThrowRangeError(const CallbackInfo& info) {
153153
throw RangeError::New(info.Env(), message);
154154
}
155155

156+
#if NAPI_VERSION > 8
157+
void ThrowSyntaxErrorCStr(const CallbackInfo& info) {
158+
std::string message = info[0].As<String>().Utf8Value();
159+
ReleaseAndWaitForChildProcess(info, 1);
160+
throw SyntaxError::New(info.Env(), message.c_str());
161+
}
162+
163+
void ThrowSyntaxErrorCtor(const CallbackInfo& info) {
164+
Napi::Value js_range_err = info[0];
165+
ReleaseAndWaitForChildProcess(info, 1);
166+
throw Napi::SyntaxError(info.Env(), js_range_err);
167+
}
168+
169+
void ThrowSyntaxError(const CallbackInfo& info) {
170+
std::string message = info[0].As<String>().Utf8Value();
171+
172+
ReleaseAndWaitForChildProcess(info, 1);
173+
throw SyntaxError::New(info.Env(), message);
174+
}
175+
#endif // NAPI_VERSION > 8
176+
156177
Value CatchError(const CallbackInfo& info) {
157178
Function thrower = info[0].As<Function>();
158179
try {
@@ -255,6 +276,27 @@ void ThrowEmptyRangeError(const CallbackInfo& info) {
255276
RangeError().ThrowAsJavaScriptException();
256277
}
257278

279+
#if NAPI_VERSION > 8
280+
void ThrowSyntaxError(const CallbackInfo& info) {
281+
std::string message = info[0].As<String>().Utf8Value();
282+
283+
ReleaseAndWaitForChildProcess(info, 1);
284+
SyntaxError::New(info.Env(), message).ThrowAsJavaScriptException();
285+
}
286+
287+
void ThrowSyntaxErrorCtor(const CallbackInfo& info) {
288+
Napi::Value js_range_err = info[0];
289+
ReleaseAndWaitForChildProcess(info, 1);
290+
SyntaxError(info.Env(), js_range_err).ThrowAsJavaScriptException();
291+
}
292+
293+
void ThrowSyntaxErrorCStr(const CallbackInfo& info) {
294+
std::string message = info[0].As<String>().Utf8Value();
295+
ReleaseAndWaitForChildProcess(info, 1);
296+
SyntaxError::New(info.Env(), message.c_str()).ThrowAsJavaScriptException();
297+
}
298+
#endif // NAPI_VERSION > 8
299+
258300
Value CatchError(const CallbackInfo& info) {
259301
Function thrower = info[0].As<Function>();
260302
thrower({});
@@ -372,6 +414,11 @@ Object InitError(Env env) {
372414
exports["throwRangeErrorCtor"] = Function::New(env, ThrowRangeErrorCtor);
373415
exports["throwRangeErrorCStr"] = Function::New(env, ThrowRangeErrorCStr);
374416
exports["throwEmptyRangeError"] = Function::New(env, ThrowEmptyRangeError);
417+
#if NAPI_VERSION > 8
418+
exports["throwSyntaxError"] = Function::New(env, ThrowSyntaxError);
419+
exports["throwSyntaxErrorCtor"] = Function::New(env, ThrowSyntaxErrorCtor);
420+
exports["throwSyntaxErrorCStr"] = Function::New(env, ThrowSyntaxErrorCStr);
421+
#endif // NAPI_VERSION > 8
375422
exports["catchError"] = Function::New(env, CatchError);
376423
exports["catchErrorMessage"] = Function::New(env, CatchErrorMessage);
377424
exports["doNotCatch"] = Function::New(env, DoNotCatch);

test/error.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ if (process.argv[2] === 'fatal') {
99

1010
module.exports = require('./common').runTestWithBindingPath(test);
1111

12+
const napiVersion = Number(process.env.NAPI_VERSION ?? process.versions.napi);
13+
1214
function test (bindingPath) {
1315
const binding = require(bindingPath);
1416
binding.error.testErrorCopySemantics();
@@ -46,6 +48,20 @@ function test (bindingPath) {
4648
return err instanceof RangeError && err.message === 'rangeTypeError';
4749
});
4850

51+
if (napiVersion > 8) {
52+
assert.throws(() => binding.error.throwSyntaxErrorCStr('test'), function (err) {
53+
return err instanceof SyntaxError && err.message === 'test';
54+
});
55+
56+
assert.throws(() => binding.error.throwSyntaxError('test'), function (err) {
57+
return err instanceof SyntaxError && err.message === 'test';
58+
});
59+
60+
assert.throws(() => binding.error.throwSyntaxErrorCtor(new SyntaxError('syntaxTypeError')), function (err) {
61+
return err instanceof SyntaxError && err.message === 'syntaxTypeError';
62+
});
63+
}
64+
4965
assert.throws(
5066
() => binding.error.doNotCatch(
5167
() => {

0 commit comments

Comments
 (0)