[gjs] Use GLib for JS logging
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Use GLib for JS logging
- Date: Tue, 7 May 2013 15:56:12 +0000 (UTC)
commit 9deaf856f3a0f686a0e1c38e70f29c2428a1d6a1
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Wed Jan 2 22:49:38 2013 +0100
Use GLib for JS logging
Reserve our custom logging framework for debug logging, and use standard
g_log functions for log() and logError().
This allows us to finally have readable error messages, it associates
them with a program and process when necessary, and it prepares us
for a future where glib logs to the journal by default.
https://bugzilla.gnome.org/show_bug.cgi?id=690984
Makefile.am | 2 +-
gi/arg.c | 12 +--
gi/boxed.c | 7 +-
gi/closure.c | 6 +-
gi/function.c | 2 +-
gi/gerror.c | 4 +-
gi/interface.c | 2 +-
gi/keep-alive.c | 12 ++--
gi/ns.c | 4 +-
gi/object.c | 2 +-
gi/param.c | 2 +-
gi/repo.c | 6 +-
gi/union.c | 2 +-
gi/value.c | 4 +-
gjs/context.c | 118 +++++++++-------------------
gjs/importer.c | 17 ++--
gjs/jsapi-private.cpp | 23 ++----
gjs/jsapi-util.c | 131 ++++++++++++--------------------
gjs/jsapi-util.h | 13 ++--
installed-tests/test/js/testSignals.js | 6 ++
util/log.c | 51 +-----------
util/log.h | 5 -
22 files changed, 151 insertions(+), 280 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 9debd81..bdf8cb8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,7 +17,7 @@ TEST_PROGS =
check_PROGRAMS = $(TEST_PROGS)
INTROSPECTION_GIRS =
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
-AM_CFLAGS = $(WARN_CFLAGS)
+AM_CFLAGS = $(WARN_CFLAGS) -DG_LOG_DOMAIN=\"Gjs\"
gjsjsdir = @gjsjsdir@
gjsoverridedir = $(gjsjsdir)/overrides
diff --git a/gi/arg.c b/gi/arg.c
index fb5e2ca..e9105d6 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -1748,8 +1748,7 @@ gjs_value_to_g_argument(JSContext *context,
break;
}
default:
- gjs_debug(GJS_DEBUG_ERROR,
- "Unhandled type %s for JavaScript to GArgument conversion",
+ g_warning("Unhandled type %s for JavaScript to GArgument conversion",
g_type_tag_to_string(type_tag));
wrong = TRUE;
report_type_mismatch = TRUE;
@@ -1899,8 +1898,7 @@ gjs_g_argument_init_default(JSContext *context,
break;
default:
- gjs_debug(GJS_DEBUG_ERROR,
- "Unhandled type %s for default GArgument initialization",
+ g_warning("Unhandled type %s for default GArgument initialization",
g_type_tag_to_string(type_tag));
break;
}
@@ -2757,8 +2755,7 @@ gjs_value_from_g_argument (JSContext *context,
break;
default:
- gjs_debug(GJS_DEBUG_ERROR,
- "Unhandled type %s converting GArgument to JavaScript",
+ g_warning("Unhandled type %s converting GArgument to JavaScript",
g_type_tag_to_string(type_tag));
return JS_FALSE;
}
@@ -3197,8 +3194,7 @@ gjs_g_arg_release_internal(JSContext *context,
break;
default:
- gjs_debug(GJS_DEBUG_ERROR,
- "Unhandled type %s releasing GArgument",
+ g_warning("Unhandled type %s releasing GArgument",
g_type_tag_to_string(type_tag));
return JS_FALSE;
}
diff --git a/gi/boxed.c b/gi/boxed.c
index 26d7f69..839846f 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -869,8 +869,7 @@ define_boxed_class_fields (JSContext *context,
* memory overhead.
*/
if (n_fields > 256) {
- gjs_debug(GJS_DEBUG_ERROR,
- "Only defining the first 256 fields in boxed type '%s'",
+ g_warning("Only defining the first 256 fields in boxed type '%s'",
g_base_info_get_name ((GIBaseInfo *)priv->info));
n_fields = 256;
}
@@ -1217,8 +1216,8 @@ gjs_define_boxed_class(JSContext *context,
NULL,
&prototype,
&constructor)) {
- gjs_log_exception(context, NULL);
- gjs_fatal("Can't init class %s", constructor_name);
+ gjs_log_exception(context);
+ g_error("Can't init class %s", constructor_name);
}
GJS_INC_COUNTER(boxed);
diff --git a/gi/closure.c b/gi/closure.c
index de6d7d6..2784a0f 100644
--- a/gi/closure.c
+++ b/gi/closure.c
@@ -271,7 +271,7 @@ gjs_closure_invoke(GClosure *closure,
if (JS_IsExceptionPending(context)) {
gjs_debug_closure("Exception was pending before invoking callback??? "
"Not expected");
- gjs_log_exception(context, NULL);
+ gjs_log_exception(context);
}
if (!gjs_call_function_value(context,
@@ -284,12 +284,12 @@ gjs_closure_invoke(GClosure *closure,
gjs_debug_closure("Closure invocation failed (exception should "
"have been thrown) closure %p callable %p",
closure, c->obj);
- if (!gjs_log_exception(context, NULL))
+ if (!gjs_log_exception(context))
gjs_debug_closure("Closure invocation failed but no exception was set?");
goto out;
}
- if (gjs_log_exception(context, NULL)) {
+ if (gjs_log_exception(context)) {
gjs_debug_closure("Closure invocation succeeded but an exception was set");
}
diff --git a/gi/function.c b/gi/function.c
index ff53eae..4de7647 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -1582,7 +1582,7 @@ function_new(JSContext *context,
/* funcs of constructor, MyConstructor.myfunc() */
NULL);
if (prototype == NULL)
- gjs_fatal("Can't init class %s", gjs_function_class.name);
+ g_error("Can't init class %s", gjs_function_class.name);
gjs_debug(GJS_DEBUG_GFUNCTION, "Initialized class %s prototype %p",
gjs_function_class.name, prototype);
diff --git a/gi/gerror.c b/gi/gerror.c
index 30e710c..3bcad05 100644
--- a/gi/gerror.c
+++ b/gi/gerror.c
@@ -441,8 +441,8 @@ gjs_define_error_class(JSContext *context,
&gjs_error_constructor_funcs[0],
&prototype,
&constructor)) {
- gjs_log_exception(context, NULL);
- gjs_fatal("Can't init class %s", constructor_name);
+ gjs_log_exception(context);
+ g_error("Can't init class %s", constructor_name);
}
GJS_INC_COUNTER(gerror);
diff --git a/gi/interface.c b/gi/interface.c
index 98be8e5..29cefe1 100644
--- a/gi/interface.c
+++ b/gi/interface.c
@@ -224,7 +224,7 @@ gjs_define_interface_class(JSContext *context,
NULL,
&prototype,
&constructor)) {
- gjs_fatal("Can't init class %s", constructor_name);
+ g_error("Can't init class %s", constructor_name);
}
GJS_INC_COUNTER(interface);
diff --git a/gi/keep-alive.c b/gi/keep-alive.c
index e933a43..08624c6 100644
--- a/gi/keep-alive.c
+++ b/gi/keep-alive.c
@@ -229,7 +229,7 @@ gjs_keep_alive_new(JSContext *context)
/* funcs of constructor, MyConstructor.myfunc() */
NULL);
if (prototype == NULL)
- gjs_fatal("Can't init class %s", gjs_keep_alive_class.name);
+ g_error("Can't init class %s", gjs_keep_alive_class.name);
gjs_debug(GJS_DEBUG_KEEP_ALIVE, "Initialized class %s prototype %p",
gjs_keep_alive_class.name, prototype);
@@ -241,8 +241,8 @@ gjs_keep_alive_new(JSContext *context)
keep_alive = JS_NewObject(context, &gjs_keep_alive_class, NULL, global);
if (keep_alive == NULL) {
- gjs_log_exception(context, NULL);
- gjs_fatal("Failed to create keep_alive object");
+ gjs_log_exception(context);
+ g_error("Failed to create keep_alive object");
}
priv = g_slice_new0(KeepAlive);
@@ -330,7 +330,7 @@ gjs_keep_alive_create(JSContext *context)
keep_alive = gjs_keep_alive_new(context);
if (!keep_alive)
- gjs_fatal("could not create keep_alive on global object, no memory?");
+ g_error("could not create keep_alive on global object, no memory?");
gjs_set_global_slot(context, GJS_GLOBAL_SLOT_KEEP_ALIVE, OBJECT_TO_JSVAL(keep_alive));
@@ -383,8 +383,8 @@ gjs_keep_alive_remove_global_child(JSContext *context,
keep_alive = gjs_keep_alive_get_global(context);
if (!keep_alive)
- gjs_fatal("no keep_alive property on the global object, have you "
- "previously added this child?");
+ g_error("no keep_alive property on the global object, have you "
+ "previously added this child?");
gjs_keep_alive_remove_child(context,
gjs_keep_alive_get_global(context),
diff --git a/gi/ns.c b/gi/ns.c
index 3ec7e5a..391397f 100644
--- a/gi/ns.c
+++ b/gi/ns.c
@@ -216,7 +216,7 @@ ns_new(JSContext *context,
/* funcs of constructor, MyConstructor.myfunc() */
NULL);
if (prototype == NULL)
- gjs_fatal("Can't init class %s", gjs_ns_class.name);
+ g_error("Can't init class %s", gjs_ns_class.name);
gjs_debug(GJS_DEBUG_GNAMESPACE, "Initialized class %s prototype %p",
gjs_ns_class.name, prototype);
@@ -224,7 +224,7 @@ ns_new(JSContext *context,
ns = JS_NewObject(context, &gjs_ns_class, NULL, global);
if (ns == NULL)
- gjs_fatal("No memory to create ns object");
+ g_error("No memory to create ns object");
priv = g_slice_new0(Ns);
diff --git a/gi/object.c b/gi/object.c
index 7426e31..9e1cf90 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -1984,7 +1984,7 @@ gjs_define_object_class(JSContext *context,
NULL,
&prototype,
&constructor)) {
- gjs_fatal("Can't init class %s", constructor_name);
+ g_error("Can't init class %s", constructor_name);
}
GJS_INC_COUNTER(object);
diff --git a/gi/param.c b/gi/param.c
index 857bc46..f2542c1 100644
--- a/gi/param.c
+++ b/gi/param.c
@@ -528,7 +528,7 @@ gjs_define_param_class(JSContext *context,
gjs_param_constructor_funcs,
&prototype,
&constructor)) {
- gjs_fatal("Can't init class %s", constructor_name);
+ g_error("Can't init class %s", constructor_name);
}
value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, G_TYPE_PARAM));
diff --git a/gi/repo.c b/gi/repo.c
index 6db129b..68bfed8 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -122,7 +122,7 @@ resolve_namespace_object(JSContext *context,
ns_name, OBJECT_TO_JSVAL(namespace),
NULL, NULL,
GJS_MODULE_PROP_FLAGS))
- gjs_fatal("no memory to define ns property");
+ g_error("no memory to define ns property");
override = lookup_override_function(context, ns_id);
if (override && !JS_CallFunctionValue (context,
@@ -282,7 +282,7 @@ repo_new(JSContext *context)
/* funcs of constructor, MyConstructor.myfunc() */
NULL);
if (prototype == NULL)
- gjs_fatal("Can't init class %s", gjs_repo_class.name);
+ g_error("Can't init class %s", gjs_repo_class.name);
gjs_debug(GJS_DEBUG_GREPO, "Initialized class %s prototype %p",
gjs_repo_class.name, prototype);
@@ -620,7 +620,7 @@ gjs_lookup_namespace_object_by_name(JSContext *context,
if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(importer), "importer",
gi_name, &girepository) ||
!JSVAL_IS_OBJECT(girepository)) {
- gjs_log_exception(context, NULL);
+ gjs_log_exception(context);
gjs_throw(context, "No gi property in importer");
goto fail;
}
diff --git a/gi/union.c b/gi/union.c
index f87a2b0..5d8825e 100644
--- a/gi/union.c
+++ b/gi/union.c
@@ -423,7 +423,7 @@ gjs_define_union_class(JSContext *context,
NULL,
&prototype,
&constructor)) {
- gjs_fatal("Can't init class %s", constructor_name);
+ g_error("Can't init class %s", constructor_name);
}
GJS_INC_COUNTER(boxed);
diff --git a/gi/value.c b/gi/value.c
index c69debe..9d6e633 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -122,7 +122,7 @@ closure_marshal(GClosure *closure,
gjs_debug(GJS_DEBUG_GCLOSURE,
"Unable to convert arg %d in order to invoke closure",
i);
- gjs_log_exception(context, NULL);
+ gjs_log_exception(context);
goto cleanup;
}
}
@@ -138,7 +138,7 @@ closure_marshal(GClosure *closure,
if (!gjs_value_to_g_value(context, rval, return_value)) {
gjs_debug(GJS_DEBUG_GCLOSURE,
"Unable to convert return value when invoking closure");
- gjs_log_exception(context, NULL);
+ gjs_log_exception(context);
goto cleanup;
}
}
diff --git a/gjs/context.c b/gjs/context.c
index e39d290..b6dd7dd 100644
--- a/gjs/context.c
+++ b/gjs/context.c
@@ -131,7 +131,7 @@ gjs_log(JSContext *context,
JS_RestoreExceptionState(context, exc_state);
if (jstr == NULL) {
- gjs_debug(GJS_DEBUG_LOG, "<cannot convert value to string>");
+ g_message("JS LOG: <cannot convert value to string>");
JS_EndRequest(context);
return JS_TRUE;
}
@@ -141,7 +141,7 @@ gjs_log(JSContext *context,
return JS_FALSE;
}
- gjs_debug(GJS_DEBUG_LOG, "%s", s);
+ g_message("JS LOG: %s", s);
g_free(s);
JS_EndRequest(context);
@@ -155,43 +155,29 @@ gjs_log_error(JSContext *context,
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 ((argc != 1 && argc != 2) ||
+ !JSVAL_IS_OBJECT (argv[0])) {
+ gjs_throw(context, "Must pass an exception and optionally a message to logError()");
}
- if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(jstr), &s)) {
- JS_EndRequest(context);
- return JS_FALSE;
+ if (argc == 2) {
+ /* 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);
+ } else {
+ jstr = NULL;
}
- gjs_debug(GJS_DEBUG_ERROR, "%s", s);
- gjs_log_exception_props(context, exc);
- g_free(s);
+ gjs_log_exception_full(context, argv[0], jstr);
JS_EndRequest(context);
JS_SET_RVAL(context, vp, JSVAL_VOID);
@@ -568,12 +554,12 @@ gjs_context_constructor (GType type,
js_context->runtime = JS_NewRuntime(32*1024*1024 /* max bytes */);
if (js_context->runtime == NULL)
- gjs_fatal("Failed to create javascript runtime");
+ g_error("Failed to create javascript runtime");
JS_SetGCParameter(js_context->runtime, JSGC_MAX_BYTES, 0xffffffff);
js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */);
if (js_context->context == NULL)
- gjs_fatal("Failed to create javascript context");
+ g_error("Failed to create javascript context");
gjs_runtime_init_for_context(js_context->runtime, js_context->context);
@@ -622,39 +608,39 @@ gjs_context_constructor (GType type,
}
if (!gjs_init_context_standard(js_context->context))
- gjs_fatal("Failed to initialize context");
+ g_error("Failed to initialize context");
js_context->global = JS_GetGlobalObject(js_context->context);
if (!JS_DefineProperty(js_context->context, js_context->global,
"window", OBJECT_TO_JSVAL(js_context->global),
NULL, NULL,
JSPROP_READONLY | JSPROP_PERMANENT))
- gjs_fatal("No memory to export global object as 'window'");
+ g_error("No memory to export global object as 'window'");
/* Define a global function called log() */
if (!JS_DefineFunction(js_context->context, js_context->global,
"log",
(JSNative)gjs_log,
1, GJS_MODULE_PROP_FLAGS))
- gjs_fatal("Failed to define log function");
+ g_error("Failed to define log function");
if (!JS_DefineFunction(js_context->context, js_context->global,
"logError",
(JSNative)gjs_log_error,
2, GJS_MODULE_PROP_FLAGS))
- gjs_fatal("Failed to define logError function");
+ g_error("Failed to define logError function");
/* Define global functions called print() and printerr() */
if (!JS_DefineFunction(js_context->context, js_context->global,
"print",
(JSNative)gjs_print,
3, GJS_MODULE_PROP_FLAGS))
- gjs_fatal("Failed to define print function");
+ g_error("Failed to define print function");
if (!JS_DefineFunction(js_context->context, js_context->global,
"printerr",
(JSNative)gjs_printerr,
4, GJS_MODULE_PROP_FLAGS))
- gjs_fatal("Failed to define printerr function");
+ g_error("Failed to define printerr function");
/* We create the global-to-runtime root importer with the
* passed-in search path. If someone else already created
@@ -665,14 +651,14 @@ gjs_context_constructor (GType type,
(const char**) js_context->search_path :
NULL,
TRUE))
- gjs_fatal("Failed to create root importer");
+ g_error("Failed to create root importer");
/* Now copy the global root importer (which we just created,
* if it didn't exist) to our global object
*/
if (!gjs_define_root_importer(js_context->context,
js_context->global))
- gjs_fatal("Failed to point 'imports' property at root importer");
+ g_error("Failed to point 'imports' property at root importer");
js_context->profiler = gjs_profiler_new(js_context->runtime);
@@ -996,7 +982,7 @@ gjs_context_eval(GjsContext *js_context,
}
/* log and clear exception if it's set (should not be, normally...) */
- if (gjs_log_exception(js_context->context, NULL)) {
+ if (gjs_log_exception(js_context->context)) {
gjs_debug(GJS_DEBUG_CONTEXT,
"Exception was set prior to JS_EvaluateScript()");
}
@@ -1016,29 +1002,14 @@ gjs_context_eval(GjsContext *js_context,
filename,
line_number,
&retval)) {
- char *message;
-
gjs_debug(GJS_DEBUG_CONTEXT,
"Script evaluation failed");
- /* if message is NULL then somehow exception wasn't set */
- message = NULL;
- gjs_log_exception(js_context->context,
- &message);
- if (message) {
- g_set_error(error,
- GJS_ERROR,
- GJS_ERROR_FAILED,
- "%s", message);
- g_free(message);
- } else {
- gjs_debug(GJS_DEBUG_CONTEXT,
- "JS_EvaluateScript() failed but no exception message?");
- g_set_error(error,
- GJS_ERROR,
- GJS_ERROR_FAILED,
- "JS_EvaluateScript() failed but no exception message?");
- }
+ gjs_log_exception(js_context->context);
+ g_set_error(error,
+ GJS_ERROR,
+ GJS_ERROR_FAILED,
+ "JS_EvaluateScript() failed");
success = FALSE;
}
@@ -1046,7 +1017,7 @@ gjs_context_eval(GjsContext *js_context,
gjs_debug(GJS_DEBUG_CONTEXT,
"Script evaluation succeeded");
- if (gjs_log_exception(js_context->context, NULL)) {
+ if (gjs_log_exception(js_context->context)) {
g_set_error(error,
GJS_ERROR,
GJS_ERROR_FAILED,
@@ -1109,24 +1080,11 @@ gjs_context_define_string_array(GjsContext *js_context,
js_context->global,
array_name, array_length, array_values,
JSPROP_READONLY | JSPROP_PERMANENT)) {
- char *message;
-
- message = NULL;
- gjs_log_exception(js_context->context, &message);
- if (message) {
- g_set_error(error,
- GJS_ERROR,
- GJS_ERROR_FAILED,
- "%s", message);
- g_free(message);
- } else {
- message = "gjs_define_string_array() failed but no exception message?";
- gjs_debug(GJS_DEBUG_CONTEXT, "%s", message);
- g_set_error(error,
- GJS_ERROR,
- GJS_ERROR_FAILED,
- "%s", message);
- }
+ gjs_log_exception(js_context->context);
+ g_set_error(error,
+ GJS_ERROR,
+ GJS_ERROR_FAILED,
+ "gjs_define_string_array() failed");
return FALSE;
}
diff --git a/gjs/importer.c b/gjs/importer.c
index 45034e1..6ee5a0d 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -350,7 +350,7 @@ load_module_init(JSContext *context,
if (JS_IsExceptionPending(context)) {
gjs_debug(GJS_DEBUG_IMPORTER,
"Module " MODULE_INIT_FILENAME " left an exception set");
- gjs_log_and_keep_exception(context, NULL);
+ gjs_log_and_keep_exception(context);
} else {
gjs_throw(context,
"JS_EvaluateScript() returned FALSE but did not set exception");
@@ -464,7 +464,7 @@ import_file(JSContext *context,
gjs_debug(GJS_DEBUG_IMPORTER,
"Module '%s' left an exception set",
name);
- gjs_log_and_keep_exception(context, NULL);
+ gjs_log_and_keep_exception(context);
} else {
gjs_throw(context,
"JS_EvaluateScript() returned FALSE but did not set exception");
@@ -1023,7 +1023,8 @@ importer_new(JSContext *context)
global = gjs_get_import_global(context);
if (!JS_HasProperty(context, global, gjs_importer_class.name, &found))
- gjs_fatal("HasProperty call failed creating importer class");
+ g_error("HasProperty call failed creating importer class");
+
if (!found) {
JSObject *prototype;
prototype = JS_InitClass(context, global,
@@ -1049,7 +1050,7 @@ importer_new(JSContext *context)
/* funcs of constructor, MyConstructor.myfunc() */
NULL);
if (prototype == NULL)
- gjs_fatal("Can't init class %s", gjs_importer_class.name);
+ g_error("Can't init class %s", gjs_importer_class.name);
gjs_debug(GJS_DEBUG_IMPORTER, "Initialized class %s prototype %p",
gjs_importer_class.name, prototype);
@@ -1057,7 +1058,7 @@ importer_new(JSContext *context)
importer = JS_NewObject(context, &gjs_importer_class, NULL, global);
if (importer == NULL)
- gjs_fatal("No memory to create importer importer");
+ g_error("No memory to create importer importer");
priv = g_slice_new0(Importer);
@@ -1152,12 +1153,12 @@ gjs_create_importer(JSContext *context,
"searchPath", -1, (const char **)search_path,
/* settable (no READONLY) but not deleteable (PERMANENT) */
JSPROP_PERMANENT | JSPROP_ENUMERATE))
- gjs_fatal("no memory to define importer search path prop");
+ g_error("no memory to define importer search path prop");
g_strfreev(search_path);
if (!define_meta_properties(context, importer, NULL, importer_name, in_object))
- gjs_fatal("failed to define meta properties on importer");
+ g_error("failed to define meta properties on importer");
return importer;
}
@@ -1178,7 +1179,7 @@ gjs_define_importer(JSContext *context,
importer_name, OBJECT_TO_JSVAL(importer),
NULL, NULL,
GJS_MODULE_PROP_FLAGS))
- gjs_fatal("no memory to define importer property");
+ g_error("no memory to define importer property");
gjs_debug(GJS_DEBUG_IMPORTER,
"Defined importer '%s' %p in %p", importer_name, importer, in_object);
diff --git a/gjs/jsapi-private.cpp b/gjs/jsapi-private.cpp
index 5f39053..9950ecd 100644
--- a/gjs/jsapi-private.cpp
+++ b/gjs/jsapi-private.cpp
@@ -44,6 +44,7 @@ gjs_error_reporter(JSContext *context,
JSErrorReport *report)
{
const char *warning;
+ GLogLevelFlags level;
if (gjs_environment_variable_is_set("GJS_ABORT_ON_OOM") &&
report->flags == JSREPORT_ERROR &&
@@ -54,11 +55,8 @@ gjs_error_reporter(JSContext *context,
}
if ((report->flags & JSREPORT_WARNING) != 0) {
- /* We manually insert "WARNING" into the output instead of
- * having GJS_DEBUG_WARNING because it's convenient to
- * search for 'JS ERROR' to find all problems
- */
- warning = "WARNING: ";
+ warning = "WARNING";
+ level = G_LOG_LEVEL_MESSAGE;
/* suppress bogus warnings. See mozilla/js/src/js.msg */
switch (report->errorNumber) {
@@ -71,18 +69,9 @@ gjs_error_reporter(JSContext *context,
return;
}
} else {
- warning = "REPORTED: ";
+ warning = "REPORTED";
+ level = G_LOG_LEVEL_WARNING;
}
- gjs_debug(GJS_DEBUG_ERROR,
- "%s'%s'",
- warning,
- message);
-
- gjs_debug(GJS_DEBUG_ERROR,
- "%sfile '%s' line %u exception %d number %d",
- warning,
- report->filename, report->lineno,
- (report->flags & JSREPORT_EXCEPTION) != 0,
- report->errorNumber);
+ g_log(G_LOG_DOMAIN, level, "JS %s: [%s %d]: %s", warning, report->filename, report->lineno, message);
}
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index bc09330..de97ab5 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -363,7 +363,7 @@ gjs_value_debug_string(JSContext *context,
return g_strdup("[out of memory copying class name]");
}
} else {
- gjs_log_exception(context, NULL);
+ gjs_log_exception(context);
JS_EndRequest(context);
return g_strdup("[unknown object]");
}
@@ -410,8 +410,7 @@ gjs_log_object_props(JSContext *context,
props_iter = JS_NewPropertyIterator(context, obj);
if (props_iter == NULL) {
- gjs_debug(GJS_DEBUG_ERROR,
- "Failed to create property iterator for object props");
+ gjs_log_exception(context);
goto done;
}
@@ -502,100 +501,70 @@ gjs_explain_scope(JSContext *context,
JS_EndRequest(context);
}
-static void
-log_one_exception_property(JSContext *context,
- JSObject *object,
- const char *name)
+JSBool
+gjs_log_exception_full(JSContext *context,
+ jsval exc,
+ JSString *message)
{
- jsval v;
- char *debugstr;
+ jsval stack;
+ JSString *exc_str;
+ char *utf8_exception, *utf8_message, *utf8_stack;
- if (!JS_GetProperty(context, object, name, &v))
- return;
+ JS_BeginRequest(context);
- debugstr = gjs_value_debug_string(context, v);
- gjs_debug(GJS_DEBUG_ERROR, " %s = '%s'", name, debugstr);
- g_free(debugstr);
-}
+ exc_str = JS_ValueToString(context, exc);
+ if (exc_str != NULL)
+ gjs_string_to_utf8(context, STRING_TO_JSVAL(exc_str), &utf8_exception);
+ else
+ utf8_exception = NULL;
-void
-gjs_log_exception_props(JSContext *context,
- jsval exc)
-{
- JS_BeginRequest(context);
+ if (message != NULL)
+ gjs_string_to_utf8(context, STRING_TO_JSVAL(message), &utf8_message);
+ else
+ utf8_message = NULL;
- /* This is useful when the exception was never sent to an error reporter
- * due to JSOPTION_DONT_REPORT_UNCAUGHT, or if the exception was not
- * a normal Error object so jsapi didn't know how to report it sensibly.
- */
- if (JSVAL_IS_NULL(exc)) {
- gjs_debug(GJS_DEBUG_ERROR,
- "Exception was null");
- } else if (JSVAL_IS_OBJECT(exc)) {
- JSObject *exc_obj;
-
- exc_obj = JSVAL_TO_OBJECT(exc);
-
- log_one_exception_property(context, exc_obj, "message");
- log_one_exception_property(context, exc_obj, "fileName");
- log_one_exception_property(context, exc_obj, "lineNumber");
- log_one_exception_property(context, exc_obj, "stack");
- } else if (JSVAL_IS_STRING(exc)) {
- gjs_debug(GJS_DEBUG_ERROR,
- "Exception was a String");
+ if (JSVAL_IS_OBJECT(exc) &&
+ gjs_object_get_property_const(context, JSVAL_TO_OBJECT(exc),
+ GJS_STRING_STACK, &stack))
+ gjs_string_to_utf8(context, stack, &utf8_stack);
+ else
+ utf8_stack = NULL;
+
+ if (utf8_message) {
+ if (utf8_stack)
+ g_warning("JS ERROR: %s: %s\n%s", utf8_message, utf8_exception, utf8_stack);
+ else
+ g_warning("JS ERROR: %s: %s", utf8_message, utf8_exception);
} else {
- gjs_debug(GJS_DEBUG_ERROR,
- "Exception had some strange type");
+ if (utf8_stack)
+ g_warning("JS ERROR: %s\n%s", utf8_exception, utf8_stack);
+ else
+ g_warning("JS ERROR: %s", utf8_exception);
}
- JS_EndRequest(context);
+
+ g_free(utf8_exception);
+ g_free(utf8_message);
+ g_free(utf8_stack);
+
+ 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_AddValueRoot(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);
+ gjs_log_exception_full(context, exc, NULL);
/* We clear above and then set it back so any exceptions
* from the logging process don't overwrite the original
@@ -614,17 +583,15 @@ log_and_maybe_keep_exception(JSContext *context,
}
JSBool
-gjs_log_exception(JSContext *context,
- char **message_p)
+gjs_log_exception(JSContext *context)
{
- return log_and_maybe_keep_exception(context, message_p, FALSE);
+ return log_and_maybe_keep_exception(context, FALSE);
}
JSBool
-gjs_log_and_keep_exception(JSContext *context,
- char **message_p)
+gjs_log_and_keep_exception(JSContext *context)
{
- return log_and_maybe_keep_exception(context, message_p, TRUE);
+ return log_and_maybe_keep_exception(context, TRUE);
}
static void
@@ -827,13 +794,13 @@ gjs_date_from_time_t (JSContext *context, time_t time)
if (!JS_GetClassObject(context, JS_GetGlobalObject(context), JSProto_Date,
&date_constructor))
- gjs_fatal("Failed to lookup Date prototype");
+ g_error("Failed to lookup Date prototype");
if (!JS_GetProperty(context, date_constructor, "prototype", &date_prototype))
- gjs_fatal("Failed to get prototype from Date constructor");
+ g_error("Failed to get prototype from Date constructor");
if (!JS_NewNumberValue(context, ((double) time) * 1000, &(args[0])))
- gjs_fatal("Failed to convert time_t to number");
+ g_error("Failed to convert time_t to number");
date = JS_New(context, JSVAL_TO_OBJECT (date_prototype), 1, args);
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 1e8aea6..6fe1df0 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -255,14 +255,15 @@ void gjs_throw_literal (JSContext *context,
const char *string);
void gjs_throw_g_error (JSContext *context,
GError *error);
-JSBool gjs_log_exception (JSContext *context,
- char **message_p);
-JSBool gjs_log_and_keep_exception (JSContext *context,
- char **message_p);
+
+JSBool gjs_log_exception (JSContext *context);
+JSBool gjs_log_and_keep_exception (JSContext *context);
JSBool gjs_move_exception (JSContext *src_context,
JSContext *dest_context);
-void gjs_log_exception_props (JSContext *context,
- jsval exc);
+JSBool gjs_log_exception_full (JSContext *context,
+ jsval exc,
+ JSString *message);
+
#ifdef __GJS_UTIL_LOG_H__
void gjs_log_object_props (JSContext *context,
JSObject *obj,
diff --git a/installed-tests/test/js/testSignals.js b/installed-tests/test/js/testSignals.js
index e0f4c83..cf41b12 100644
--- a/installed-tests/test/js/testSignals.js
+++ b/installed-tests/test/js/testSignals.js
@@ -1,5 +1,7 @@
// application/javascript;version=1.8
const JSUnit = imports.jsUnit;
+const GLib = imports.gi.GLib;
+
const Signals = imports.signals;
function Foo() {
@@ -120,11 +122,15 @@ function testExceptionInCallback() {
});
// exception in callback does not effect other callbacks
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+ 'JS ERROR: Exception in callback for signal: *');
foo.emit('bar');
JSUnit.assertEquals(1, foo.bar1Called);
JSUnit.assertEquals(1, foo.bar2Called);
// exception in callback does not disconnect the callback
+ GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
+ 'JS ERROR: Exception in callback for signal: *');
foo.emit('bar');
JSUnit.assertEquals(2, foo.bar1Called);
JSUnit.assertEquals(2, foo.bar2Called);
diff --git a/util/log.c b/util/log.c
index 1475d25..c2e3220 100644
--- a/util/log.c
+++ b/util/log.c
@@ -33,30 +33,6 @@
#include <sys/types.h>
#include <unistd.h>
-void
-gjs_fatal(const char *format, ...)
-{
- va_list args;
- char *s;
-
- va_start (args, format);
- s = g_strdup_vprintf (format, args);
- va_end (args);
-
- fputs(s, stderr);
-
- if (!g_str_has_suffix(s, "\n"))
- fputs("\n", stderr);
- fputs("\n", stderr);
-
- fflush(stderr);
-
- g_free(s);
-
- abort();
- exit(1); /* not reached unless there's some weird SIGABRT handler */
-}
-
/* prefix is allowed if it's in the ;-delimited environment variable
* GJS_DEBUG_TOPICS or if that variable is not set.
*/
@@ -95,14 +71,13 @@ is_allowed_prefix (const char *prefix)
static void
write_to_stream(FILE *logfp,
- gboolean error,
const char *prefix,
const char *s)
{
/* seek to end to avoid truncating in case we're using shared logfile */
(void)fseek(logfp, 0, SEEK_END);
- fprintf(logfp, "%*s: %s%s", PREFIX_LENGTH, prefix, error ? "!!! " : "", s);
+ fprintf(logfp, "%*s: %s", PREFIX_LENGTH, prefix, s);
if (!g_str_has_suffix(s, "\n"))
fputs("\n", logfp);
fflush(logfp);
@@ -122,7 +97,6 @@ gjs_debug(GjsDebugTopic topic,
const char *prefix;
va_list args;
char *s;
- gboolean error;
if (!checked_for_timestamp) {
print_timestamp = gjs_environment_variable_is_set("GJS_DEBUG_TIMESTAMP");
@@ -175,15 +149,13 @@ gjs_debug(GjsDebugTopic topic,
strace_timestamps = gjs_environment_variable_is_set("GJS_STRACE_TIMESTAMPS");
}
- /* only log errors and strace timestamps if debug
+ /* only strace timestamps if debug
* log wasn't specifically switched on
*/
- if ((!debug_log_enabled) &&
- !(topic == GJS_DEBUG_ERROR ||
- topic == GJS_DEBUG_STRACE_TIMESTAMP))
+ if (!debug_log_enabled &&
+ topic != GJS_DEBUG_STRACE_TIMESTAMP)
return;
- error = FALSE;
switch (topic) {
case GJS_DEBUG_STRACE_TIMESTAMP:
/* return early if strace timestamps are disabled, avoiding
@@ -200,16 +172,9 @@ gjs_debug(GjsDebugTopic topic,
case GJS_DEBUG_GI_USAGE:
prefix = "JS GI USE";
break;
- case GJS_DEBUG_ERROR:
- prefix = "JS ERROR";
- error = TRUE;
- break;
case GJS_DEBUG_MEMORY:
prefix = "JS MEMORY";
break;
- case GJS_DEBUG_LOG:
- prefix = "JS LOG";
- break;
case GJS_DEBUG_CONTEXT:
prefix = "JS CTX";
break;
@@ -318,13 +283,7 @@ gjs_debug(GjsDebugTopic topic,
previous = total;
}
- /* write to both stderr and logfile
- * if it's an error
- */
- if (error && logfp != stderr)
- write_to_stream(stderr, error, prefix, s);
-
- write_to_stream(logfp, error, prefix, s);
+ write_to_stream(logfp, prefix, s);
}
g_free(s);
diff --git a/util/log.h b/util/log.h
index 05937fb..83f0338 100644
--- a/util/log.h
+++ b/util/log.h
@@ -36,9 +36,7 @@ G_BEGIN_DECLS
typedef enum {
GJS_DEBUG_STRACE_TIMESTAMP,
GJS_DEBUG_GI_USAGE,
- GJS_DEBUG_ERROR,
GJS_DEBUG_MEMORY,
- GJS_DEBUG_LOG,
GJS_DEBUG_CONTEXT,
GJS_DEBUG_IMPORTER,
GJS_DEBUG_NATIVE,
@@ -153,9 +151,6 @@ typedef enum {
#define gjs_debug_gsignal(format...)
#endif
-void gjs_fatal(const char *format,
- ...) G_GNUC_PRINTF (1, 2) G_GNUC_NORETURN;
-
void gjs_debug(GjsDebugTopic topic,
const char *format,
...) G_GNUC_PRINTF (2, 3);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]