[gjs/wip/ptomato/730101: 18/19] jsapi-util-error: Allow throwing custom 'name' property
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/730101: 18/19] jsapi-util-error: Allow throwing custom 'name' property
- Date: Wed, 28 Dec 2016 02:00:14 +0000 (UTC)
commit ca2f4e0dda82a858b124d8b5048e39f3b2c04ee7
Author: Philip Chimento <philip endlessm com>
Date: Thu Dec 22 16:49:17 2016 -0700
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
gi/boxed.cpp | 6 +++---
gi/fundamental.cpp | 4 ++--
gi/param.cpp | 4 ++--
gi/union.cpp | 6 +++---
gjs/jsapi-dynamic-class.cpp | 2 +-
gjs/jsapi-util-error.cpp | 31 ++++++++++++++++++++++++-------
gjs/jsapi-util.h | 3 ++-
7 files changed, 37 insertions(+), 19 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 97f92cf..4447ed7 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -1260,7 +1260,7 @@ gjs_typecheck_boxed(JSContext *context,
if (priv->gboxed == NULL) {
if (throw_error) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is %s.%s.prototype, not an object instance - cannot convert to a boxed
instance",
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
@@ -1278,14 +1278,14 @@ gjs_typecheck_boxed(JSContext *context,
if (!result && throw_error) {
if (expected_info != NULL) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s.%s - cannot convert to %s.%s",
g_base_info_get_namespace((GIBaseInfo*) priv->info),
g_base_info_get_name((GIBaseInfo*) priv->info),
g_base_info_get_namespace((GIBaseInfo*) expected_info),
g_base_info_get_name((GIBaseInfo*) expected_info));
} else {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s.%s - cannot convert to %s",
g_base_info_get_namespace((GIBaseInfo*) priv->info),
g_base_info_get_name((GIBaseInfo*) priv->info),
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 1a0c96a..56c7121 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -849,13 +849,13 @@ gjs_typecheck_fundamental(JSContext *context,
if (!result && throw_error) {
if (priv->prototype->info) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s.%s - cannot convert to %s",
g_base_info_get_namespace((GIBaseInfo *) priv->prototype->info),
g_base_info_get_name((GIBaseInfo *) priv->prototype->info),
g_type_name(expected_gtype));
} else {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s - cannot convert to %s",
g_type_name(priv->prototype->gtype),
g_type_name(expected_gtype));
diff --git a/gi/param.cpp b/gi/param.cpp
index 84a0e54..1b18150 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -305,7 +305,7 @@ gjs_typecheck_param(JSContext *context,
if (priv->gparam == NULL) {
if (throw_error) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is GObject.ParamSpec.prototype, not an object instance - "
"cannot convert to a GObject.ParamSpec instance");
}
@@ -319,7 +319,7 @@ gjs_typecheck_param(JSContext *context,
result = true;
if (!result && throw_error) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s - cannot convert to %s",
g_type_name(G_TYPE_FROM_INSTANCE (priv->gparam)),
g_type_name(expected_type));
diff --git a/gi/union.cpp b/gi/union.cpp
index 28db3dc..38a1405 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -444,7 +444,7 @@ gjs_typecheck_union(JSContext *context,
if (priv->gboxed == NULL) {
if (throw_error) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is %s.%s.prototype, not an object instance - cannot convert to a union
instance",
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
@@ -462,14 +462,14 @@ gjs_typecheck_union(JSContext *context,
if (!result && throw_error) {
if (expected_info != NULL) {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s.%s - cannot convert to %s.%s",
g_base_info_get_namespace((GIBaseInfo*) priv->info),
g_base_info_get_name((GIBaseInfo*) priv->info),
g_base_info_get_namespace((GIBaseInfo*) expected_info),
g_base_info_get_name((GIBaseInfo*) expected_info));
} else {
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object is of type %s.%s - cannot convert to %s",
g_base_info_get_namespace((GIBaseInfo*) priv->info),
g_base_info_get_name((GIBaseInfo*) priv->info),
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index 5edc0f1..e229215 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -151,7 +151,7 @@ gjs_typecheck_instance(JSContext *context,
if (throw_error) {
const JSClass *obj_class = JS_GetClass(obj);
- gjs_throw_custom(context, "TypeError",
+ gjs_throw_custom(context, "TypeError", NULL,
"Object %p is not a subclass of %s, it's a %s",
obj.get(), static_clasp->name,
format_dynamic_class_name(obj_class->name));
diff --git a/gjs/jsapi-util-error.cpp b/gjs/jsapi-util-error.cpp
index bea2694..de890f1 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);
}
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 9f7c945..79d64fb 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -361,8 +361,9 @@ void gjs_throw (JSContext *context,
...) G_GNUC_PRINTF (2, 3);
void gjs_throw_custom (JSContext *context,
const char *error_class,
+ const char *error_name,
const char *format,
- ...) G_GNUC_PRINTF (3, 4);
+ ...) G_GNUC_PRINTF (4, 5);
void gjs_throw_literal (JSContext *context,
const char *string);
void gjs_throw_g_error (JSContext *context,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]