Skip to content

Commit

Permalink
Merge pull request nodejs#147 from boingoing/add_napi_is_error
Browse files Browse the repository at this point in the history
napi: Add napi_is_error API to identify NativeError objects
  • Loading branch information
boingoing authored Mar 15, 2017
2 parents 45f84c7 + fc66f89 commit df2a9e2
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/node_jsvmapi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,16 @@ napi_status napi_throw_range_error(napi_env e, const char* msg) {
return napi_ok;
}

napi_status napi_is_error(napi_env e, napi_value v, bool* result) {
// Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw JS exceptions.
CHECK_ARG(result);

v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(v);
*result = value->IsNativeError();

return napi_ok;
}

napi_status napi_get_value_double(napi_env e, napi_value v, double* result) {
// Omit NAPI_PREAMBLE and GET_RETURN_STATUS because V8 calls here cannot throw JS exceptions.
CHECK_ARG(result);
Expand Down
1 change: 1 addition & 0 deletions src/node_jsvmapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ NODE_EXTERN napi_status napi_throw(napi_env e, napi_value error);
NODE_EXTERN napi_status napi_throw_error(napi_env e, const char* msg);
NODE_EXTERN napi_status napi_throw_type_error(napi_env e, const char* msg);
NODE_EXTERN napi_status napi_throw_range_error(napi_env e, const char* msg);
NODE_EXTERN napi_status napi_is_error(napi_env e, napi_value v, bool* result);

// Methods to support catching exceptions
NODE_EXTERN napi_status napi_is_exception_pending(napi_env e, bool* result);
Expand Down
8 changes: 8 additions & 0 deletions test/addons-abi/test_error/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"targets": [
{
"target_name": "test_error",
"sources": [ "test_error.cc" ]
}
]
}
51 changes: 51 additions & 0 deletions test/addons-abi/test_error/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

const common = require('../../common');
const test_error = require(`./build/${common.buildType}/test_error`);
const assert = require('assert');
const theError = new Error('Some error');
const theTypeError = new TypeError('Some type error');
const theSyntaxError = new SyntaxError('Some syntax error');
const theRangeError = new RangeError('Some type error');
const theReferenceError = new ReferenceError('Some reference error');
const theURIError = new URIError('Some URI error');
const theEvalError = new EvalError('Some eval error');

class MyError extends Error { }
const myError = new MyError('Some MyError');

// Test that native error object is correctly classed
assert.strictEqual(test_error.checkError(theError), true,
'Error object correctly classed by napi_is_error');

// Test that native type error object is correctly classed
assert.strictEqual(test_error.checkError(theTypeError), true,
'Type error object correctly classed by napi_is_error');

// Test that native syntax error object is correctly classed
assert.strictEqual(test_error.checkError(theSyntaxError), true,
'Syntax error object correctly classed by napi_is_error');

// Test that native range error object is correctly classed
assert.strictEqual(test_error.checkError(theRangeError), true,
'Range error object correctly classed by napi_is_error');

// Test that native URI error object is correctly classed
assert.strictEqual(test_error.checkError(theURIError), true,
'URI error object correctly classed by napi_is_error');

// Test that native eval error object is correctly classed
assert.strictEqual(test_error.checkError(theEvalError), true,
'Eval error object correctly classed by napi_is_error');

// Test that class derived from native error is correctly classed
assert.strictEqual(test_error.checkError(myError), true,
'Class derived from native error correctly classed by napi_is_error');

// Test that non-error object is correctly classed
assert.strictEqual(test_error.checkError({}), false,
'Non-error object correctly classed by napi_is_error');

// Test that non-error primitive is correctly classed
assert.strictEqual(test_error.checkError('non-object'), false,
'Non-error primitive correctly classed by napi_is_error');
38 changes: 38 additions & 0 deletions test/addons-abi/test_error/test_error.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <node_jsvmapi.h>

void checkError(napi_env e, napi_callback_info info) {
napi_status status;
napi_value jsError;

status = napi_get_cb_args(e, info, &jsError, 1);
if (status != napi_ok) return;

bool r;
status = napi_is_error(e, jsError, &r);
if (status != napi_ok) return;

napi_value result;
if (r) {
status = napi_get_true(e, &result);
} else {
status = napi_get_false(e, &result);
}
if (status != napi_ok) return;

status = napi_set_return_value(e, info, result);
if (status != napi_ok) return;
}

void Init(napi_env env, napi_value exports, napi_value module) {
napi_status status;

napi_property_descriptor descriptors[] = {
{ "checkError", checkError }
};

status = napi_define_properties(
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors);
if (status != napi_ok) return;
}

NODE_MODULE_ABI(addon, Init)

0 comments on commit df2a9e2

Please sign in to comment.