0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::js: Improve exception sequence / Add script and line data.

This commit is contained in:
Jason Volk 2016-10-21 22:31:30 -07:00
parent f9848b0494
commit 2d89f0e97c
2 changed files with 43 additions and 13 deletions

View file

@ -32,6 +32,7 @@ struct jserror
JS::PersistentRootedValue val; JS::PersistentRootedValue val;
void create(JSErrorReport &);
void create(const JSErrorReport &); void create(const JSErrorReport &);
void generate(const JSExnType &type, const char *const &fmt, va_list ap); void generate(const JSExnType &type, const char *const &fmt, va_list ap);
void set_pending() const; void set_pending() const;

View file

@ -854,23 +854,33 @@ ircd::js::jserror::jserror(pending_t)
:ircd::js::error{generate_skip} :ircd::js::error{generate_skip}
,val{*cx} ,val{*cx}
{ {
if(!restore_exception(*cx)) if(unlikely(!restore_exception(*cx)))
{
snprintf(ircd::exception::buf, sizeof(ircd::exception::buf),
"(internal error): Failed to restore exception.");
return; return;
}
auto &report(cx->report); auto &report(cx->report);
if(report.flags & JSREPORT_EXCEPTION && if(JS_GetPendingException(*cx, &val))
report.errorNumber != 105)
{ {
JS::RootedObject obj(*cx, &val.toObject()); JS::RootedObject obj(*cx, &val.toObject());
if(likely(JS_ErrorFromException(*cx, obj))) if(likely(JS_ErrorFromException(*cx, obj)))
report = *JS_ErrorFromException(*cx, obj); report = *JS_ErrorFromException(*cx, obj);
char linebuf[64];
snprintf(linebuf, sizeof(linebuf), "@%u+%u: ",
report.lineno,
report.column);
const auto msg(report.ucmessage? string::convert(report.ucmessage) : std::string{}); const auto msg(report.ucmessage? string::convert(report.ucmessage) : std::string{});
snprintf(ircd::exception::buf, sizeof(ircd::exception::buf), "%s%s%s", snprintf(ircd::exception::buf, sizeof(ircd::exception::buf), "%s%s%s%s",
reflect((JSExnType)report.exnType), reflect((JSExnType)report.exnType),
msg.empty()? "." : ": ", msg.empty()? "." : ": ",
msg.empty()? "" : linebuf,
msg.c_str()); msg.c_str());
JS_ClearPendingException(*cx);
return; return;
} }
@ -922,20 +932,39 @@ ircd::js::jserror::generate(const JSExnType &type,
void void
ircd::js::jserror::create(const JSErrorReport &report) ircd::js::jserror::create(const JSErrorReport &report)
{ {
const auto type((JSExnType)report.exnType); JSErrorReport cpy(report);
const auto &col(report.column); create(cpy);
const auto &line(report.lineno); }
JS::RootedString msg(*cx); void
JS::RootedString file(*cx); ircd::js::jserror::create(JSErrorReport &report)
JS::RootedObject stack(*cx); {
JS::AutoFilename fn;
const auto col(report.column? nullptr : &report.column);
const auto line(report.lineno? nullptr : &report.lineno);
DescribeScriptedCaller(*cx, &fn, line, col);
JS::RootedString msg
{
*cx,
JS_NewUCStringCopyZ(*cx, report.ucmessage)
};
JS::RootedString file
{
*cx,
JS_NewStringCopyZ(*cx, fn.get()?: "<unknown>")
};
JS::RootedObject stack(*cx, nullptr);
const auto type((JSExnType)report.exnType);
if(!JS::CreateError(*cx, if(!JS::CreateError(*cx,
type, type,
stack, stack,
file, file,
line, report.lineno,
col, report.column,
const_cast<JSErrorReport *>(&report), &report,
msg, msg,
&val)) &val))
{ {