[gjs: 8/12] gerror: Make gjs_gerror_make_from_error() infallible
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 8/12] gerror: Make gjs_gerror_make_from_error() infallible
- Date: Sun, 11 Apr 2021 23:22:50 +0000 (UTC)
commit fcdf9d01e6fef61e4f74a5a53a675fdcff08d0dc
Author: Philip Chimento <philip chimento gmail com>
Date: Sun Mar 21 20:15:17 2021 -0700
gerror: Make gjs_gerror_make_from_error() infallible
In the case where the JS engine fails to convert a JS exception into a
GError, we still want to have some GError to return to the caller, so
return a GJS_JS_ERROR_INTERNAL_ERROR with a generic message.
gi/function.cpp | 12 +++++-------
gi/gerror.cpp | 27 +++++++++++++++++++++++----
2 files changed, 28 insertions(+), 11 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index be84cb8a..687eee96 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -416,13 +416,11 @@ void GjsCallbackTrampoline::callback_closure(GIArgument** args, void* result) {
GError* local_error =
gjs_gerror_make_from_error(context, exc_object);
- if (local_error) {
- // the GError ** pointer is the last argument, and is not
- // included in the n_args
- auto* gerror = gjs_arg_get<GError**>(error_argument);
- g_propagate_error(gerror, local_error);
- JS_ClearPendingException(context); // don't log
- }
+ // the GError ** pointer is the last argument, and is not
+ // included in the n_args
+ auto* gerror = gjs_arg_get<GError**>(error_argument);
+ g_propagate_error(gerror, local_error);
+ JS_ClearPendingException(context); // don't log
} else if (!rval.isUndefined()) {
JS_SetPendingException(context, rval);
}
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 82e80e12..ddbae7db 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -426,10 +426,8 @@ bool ErrorBase::typecheck(JSContext* cx, JS::HandleObject obj,
return GIWrapperBase::typecheck(cx, obj, nullptr, G_TYPE_ERROR, no_throw);
}
-GError *
-gjs_gerror_make_from_error(JSContext *cx,
- JS::HandleObject obj)
-{
+GJS_JSAPI_RETURN_CONVENTION
+static GError* gerror_from_error_impl(JSContext* cx, JS::HandleObject obj) {
if (ErrorBase::typecheck(cx, obj, GjsTypecheckNoThrow())) {
/* This is already a GError, just copy it */
GError* inner = ErrorBase::to_c_ptr(cx, obj);
@@ -468,6 +466,27 @@ gjs_gerror_make_from_error(JSContext *cx,
return g_error_new_literal(GJS_JS_ERROR, code, message.get());
}
+/*
+ * gjs_gerror_make_from_error:
+ *
+ * Attempts to convert a JavaScript exception into a #GError. This function is
+ * infallible and will always return a #GError with some message, even if the
+ * exception object couldn't be converted.
+ *
+ * Returns: (transfer full): a new #GError
+ */
+GError* gjs_gerror_make_from_error(JSContext* cx, JS::HandleObject obj) {
+ GError* retval = gerror_from_error_impl(cx, obj);
+ if (retval)
+ return retval;
+
+ // Make a GError with an InternalError even if it wasn't possible to convert
+ // the exception into one
+ gjs_log_exception(cx); // log the inner exception
+ return g_error_new_literal(GJS_JS_ERROR, GJS_JS_ERROR_INTERNAL_ERROR,
+ "Failed to convert JS exception into GError");
+}
+
/*
* gjs_throw_gerror:
*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]