diff options
author | Philip Chimento <philip@endlessm.com> | 2016-12-22 16:49:17 -0700 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2016-12-27 23:46:05 -0700 |
commit | 5ce1116af6641035d1a360e4919f6e9fc1924c61 (patch) | |
tree | 7afa6fd61c4a040eb1103887f33c6b45d4f2f600 /gjs/jsapi-util-error.cpp | |
parent | 655750cee75622be18c1b788609efd72f8265bd8 (diff) | |
download | gjs-5ce1116af6641035d1a360e4919f6e9fc1924c61.tar.gz |
jsapi-util-error: Allow throwing custom 'name' property
According to MDN [1], an idiomatic way to indicate a custom error is by
setting the 'name' property:
var e = new Error('Malformed input'); // e.name is 'Error'
e.name = 'ParseError';
throw e;
// e.toString() would return 'ParseError: Malformed input'
Add an extra 'name' argument to gjs_throw_custom() to allow this. If
'name' is NULL, then the previous behaviour is maintained.
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name
https://bugzilla.gnome.org/show_bug.cgi?id=730101
Diffstat (limited to 'gjs/jsapi-util-error.cpp')
-rw-r--r-- | gjs/jsapi-util-error.cpp | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/gjs/jsapi-util-error.cpp b/gjs/jsapi-util-error.cpp index bea26948..de890f10 100644 --- a/gjs/jsapi-util-error.cpp +++ b/gjs/jsapi-util-error.cpp @@ -42,9 +42,10 @@ * http://egachine.berlios.de/embedding-sm-best-practice/embedding-sm-best-practice.html#error-handling */ static void -G_GNUC_PRINTF(3, 0) +G_GNUC_PRINTF(4, 0) gjs_throw_valist(JSContext *context, const char *error_class, + const char *error_name, const char *format, va_list args) { @@ -76,7 +77,8 @@ gjs_throw_valist(JSContext *context, JS::RootedObject constructor(context); JS::RootedObject global(context, JS::CurrentGlobalOrNull(context)); - JS::RootedValue v_constructor(context), new_exc(context); + JS::RootedValue v_constructor(context), exc_val(context); + JS::RootedObject new_exc(context); JS::AutoValueArray<1> error_args(context); result = false; @@ -93,8 +95,22 @@ gjs_throw_valist(JSContext *context, /* throw new Error(message) */ constructor = &v_constructor.toObject(); - new_exc.setObjectOrNull(JS_New(context, constructor, error_args)); - JS_SetPendingException(context, new_exc); + new_exc = JS_New(context, constructor, error_args); + + if (new_exc == NULL) + goto out; + + if (error_name != NULL) { + JS::RootedId name_id(context, + gjs_context_get_const_string(context, GJS_STRING_NAME)); + JS::RootedValue name_value(context); + if (!gjs_string_from_utf8(context, error_name, -1, &name_value) || + !JS_SetPropertyById(context, new_exc, name_id, name_value)) + goto out; + } + + exc_val.setObject(*new_exc); + JS_SetPendingException(context, exc_val); result = true; @@ -128,25 +144,26 @@ gjs_throw(JSContext *context, va_list args; va_start(args, format); - gjs_throw_valist(context, "Error", format, args); + gjs_throw_valist(context, "Error", NULL, format, args); va_end(args); } /* * Like gjs_throw, but allows to customize the error - * class. Mainly used for throwing TypeError instead of + * class and 'name' property. Mainly used for throwing TypeError instead of * error. */ void gjs_throw_custom(JSContext *context, const char *error_class, + const char *error_name, const char *format, ...) { va_list args; va_start(args, format); - gjs_throw_valist(context, error_class, format, args); + gjs_throw_valist(context, error_class, error_name, format, args); va_end(args); } |