static JSBool gjs_log_error(JSContext *context, uintN argc, jsval *vp) { jsval *argv = JS_ARGV(context, vp); char *s; JSExceptionState *exc_state; JSString *jstr; jsval exc; if (argc != 2) { gjs_throw(context, "Must pass an exception and message string to logError()"); return JS_FALSE; } JS_BeginRequest(context); exc = argv[0]; /* JS_ValueToString might throw, in which we will only *log that the value could be converted to string */ exc_state = JS_SaveExceptionState(context); jstr = JS_ValueToString(context, argv[1]); if (jstr != NULL) argv[1] = STRING_TO_JSVAL(jstr); // GC root JS_RestoreExceptionState(context, exc_state); if (jstr == NULL) { gjs_debug(GJS_DEBUG_ERROR, "<cannot convert value to string>"); gjs_log_exception_props(context, exc); JS_EndRequest(context); return JS_TRUE; } if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(jstr), &s)) { JS_EndRequest(context); return JS_FALSE; } gjs_debug(GJS_DEBUG_ERROR, "%s", s); gjs_log_exception_props(context, exc); g_free(s); JS_EndRequest(context); JS_SET_RVAL(context, vp, JSVAL_VOID); return JS_TRUE; }
static JSBool log_and_maybe_keep_exception(JSContext *context, char **message_p, gboolean keep) { jsval exc = JSVAL_VOID; JSString *s; char *message; JSBool retval = JS_FALSE; JS_BeginRequest(context); if (message_p) *message_p = NULL; JS_AddRoot(context, &exc); if (!JS_GetPendingException(context, &exc)) goto out; JS_ClearPendingException(context); s = JS_ValueToString(context, exc); if (s == NULL) { gjs_debug(GJS_DEBUG_ERROR, "Failed to convert exception to string"); goto out; /* Exception should be thrown already */ } if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(s), &message)) { gjs_debug(GJS_DEBUG_ERROR, "Failed to convert exception string to UTF-8"); goto out; /* Error already set */ } gjs_debug(GJS_DEBUG_ERROR, "Exception was: %s", message); if (message_p) { *message_p = message; } else { g_free(message); } gjs_log_exception_props(context, exc); /* We clear above and then set it back so any exceptions * from the logging process don't overwrite the original */ if (keep) JS_SetPendingException(context, exc); retval = JS_TRUE; out: JS_RemoveRoot(context, &exc); JS_EndRequest(context); return retval; }