diff --git a/include/ircd/js/error.h b/include/ircd/js/error.h index a9a8b0413..dbf14401a 100644 --- a/include/ircd/js/error.h +++ b/include/ircd/js/error.h @@ -44,6 +44,8 @@ struct jserror jserror(generate_skip_t); jserror(const JSErrorReport &); jserror(const char *fmt = " ", ...) AFP(2, 3); + jserror(JSObject &); + jserror(JSObject *const &); jserror(const JS::Value &); }; diff --git a/ircd/js.cc b/ircd/js.cc index f2cda1058..6ee3c7a08 100644 --- a/ircd/js.cc +++ b/ircd/js.cc @@ -1685,6 +1685,18 @@ ircd::js::jserror::jserror(const JS::Value &val) { } +ircd::js::jserror::jserror(JSObject *const &obj) +:ircd::js::error{generate_skip} +,val{obj? JS::ObjectValue(*obj) : JS::UndefinedValue() } +{ +} + +ircd::js::jserror::jserror(JSObject &obj) +:ircd::js::error{generate_skip} +,val{JS::ObjectValue(obj)} +{ +} + ircd::js::jserror::jserror(generate_skip_t) :ircd::js::error(generate_skip) ,val{} @@ -1759,7 +1771,8 @@ void ircd::js::jserror::set_pending() const { - JS_SetPendingException(*cx, value(val)); + JS_SetPendingException(*cx, &val); + save_exception(*cx, *JS_ErrorFromException(*cx, object(val.get()))); } void @@ -1819,6 +1832,14 @@ ircd::js::jserror::create(JSErrorReport &report) throw error("Failed to construct jserror exception!"); } + JS::Rooted obj(*cx); + if(unlikely(!JS_ValueToObject(*cx, &val, &obj))) + throw error("Failed to convert value to object on exception!"); + + JS::Rooted msgv(*cx, JS::StringValue(msg)); + if(unlikely(!JS_SetProperty(*cx, obj, "message", msgv))) + throw error("Failed to set jserror.message property on exception!"); + generate_what_our(report); } @@ -2553,7 +2574,11 @@ ircd::js::save_exception(context &c, const JSErrorReport &report) { if(c.except) - throw error("(internal error): Won't overwrite saved exception"); + { + //throw error("(internal error): Won't overwrite saved exception"); + log.warning("save_exception(): Dropping unrestored exception @ %p", (const void *)c.except); + JS_DropExceptionState(*cx, c.except); + } c.except = JS_SaveExceptionState(c), c.report = report; @@ -2993,17 +3018,20 @@ ircd::js::runtime::handle_error(JSContext *const ctx, noexcept { assert(report); -/* log.debug("JSContext(%p) Error report: %s [%s]", (const void *)ctx, msg, debug(*report).c_str()); -*/ /* log.critical("Unhandled: JSContext(%p): %s [%s]", (const void *)ctx, msg, debug(*report).c_str()); */ + + //TODO: warnings + if(!JSREPORT_IS_EXCEPTION(report->flags)) + return; + save_exception(our(ctx), *report); }