From 48bda833a2747ba506d7c7b56eb44f1f46ddbe22 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 8 Sep 2014 16:30:11 -0700 Subject: [PATCH] Bug 1062077 - Report exceptions immediately for non-window globals, and assert that we have a window in ScriptErrorEvent. r=bz Note that this is a no-op right now, because NS_ScriptErrorReporter currently relies on nsIScriptContext to get its global, and thus will only ever operate on window globals. But that will change once we merge this code with that in xpc::SystemErrorReporter. --- dom/base/nsJSEnvironment.cpp | 96 +++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index b9dbb4cdcaa0..87c4370e30c6 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -366,58 +366,57 @@ public: { nsEventStatus status = nsEventStatus_eIgnore; nsPIDOMWindow* win = mReport->mWindow; + MOZ_ASSERT(win); // First, notify the DOM that we have a script error, but only if - // our window is still the current inner, if we're associated with a window. - if (mDispatchEvent && (!win || win->IsCurrentInnerWindow())) { - nsIDocShell* docShell = win ? win->GetDocShell() : nullptr; - if (docShell && - !JSREPORT_IS_WARNING(mReport->mFlags) && - !sHandlingScriptError) { - AutoRestore recursionGuard(sHandlingScriptError); - sHandlingScriptError = true; + // our window is still the current inner. + if (mDispatchEvent && win->IsCurrentInnerWindow() && + win->GetDocShell() && !JSREPORT_IS_WARNING(mReport->mFlags) && + !sHandlingScriptError) + { + AutoRestore recursionGuard(sHandlingScriptError); + sHandlingScriptError = true; - nsRefPtr presContext; - docShell->GetPresContext(getter_AddRefs(presContext)); + nsRefPtr presContext; + win->GetDocShell()->GetPresContext(getter_AddRefs(presContext)); - ThreadsafeAutoJSContext cx; - RootedDictionary init(cx); - init.mCancelable = true; - init.mFilename = mReport->mFileName; - init.mBubbles = true; + ThreadsafeAutoJSContext cx; + RootedDictionary init(cx); + init.mCancelable = true; + init.mFilename = mReport->mFileName; + init.mBubbles = true; - nsCOMPtr sop(do_QueryInterface(win)); - NS_ENSURE_STATE(sop); - nsIPrincipal* p = sop->GetPrincipal(); - NS_ENSURE_STATE(p); + nsCOMPtr sop(do_QueryInterface(win)); + NS_ENSURE_STATE(sop); + nsIPrincipal* p = sop->GetPrincipal(); + NS_ENSURE_STATE(p); - bool sameOrigin = !mOriginPrincipal; + bool sameOrigin = !mOriginPrincipal; - if (p && !sameOrigin) { - if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) { - sameOrigin = false; - } + if (p && !sameOrigin) { + if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) { + sameOrigin = false; } - - NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error."); - if (sameOrigin) { - init.mMessage = mReport->mErrorMsg; - init.mLineno = mReport->mLineNumber; - init.mColno = mReport->mColumn; - init.mError = mError; - } else { - NS_WARNING("Not same origin error!"); - init.mMessage = xoriginMsg; - init.mLineno = 0; - } - - nsRefPtr event = - ErrorEvent::Constructor(static_cast(win), - NS_LITERAL_STRING("error"), init); - event->SetTrusted(true); - - EventDispatcher::DispatchDOMEvent(win, nullptr, event, presContext, - &status); } + + NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error."); + if (sameOrigin) { + init.mMessage = mReport->mErrorMsg; + init.mLineno = mReport->mLineNumber; + init.mColno = mReport->mColumn; + init.mError = mError; + } else { + NS_WARNING("Not same origin error!"); + init.mMessage = xoriginMsg; + init.mLineno = 0; + } + + nsRefPtr event = + ErrorEvent::Constructor(static_cast(win), + NS_LITERAL_STRING("error"), init); + event->SetTrusted(true); + + EventDispatcher::DispatchDOMEvent(win, nullptr, event, presContext, + &status); } if (status != nsEventStatus_eConsumeNoDefault) { @@ -465,6 +464,15 @@ NS_ScriptErrorReporter(JSContext *cx, nsRefPtr xpcReport = new xpc::ErrorReport(); xpcReport->Init(report, message, globalObject); + // If there's no window to fire an event at, report it to the console + // directly. + if (!xpcReport->mWindow) { + xpcReport->LogToConsole(); + return; + } + + // Otherwise, we need to asynchronously invoke onerror before we can decide + // whether or not to report the error to the console. nsContentUtils::AddScriptRunner( new ScriptErrorEvent(JS_GetRuntime(cx), xpcReport,