Bug 1141222 - Create ScriptError with stack from Cu.reportError. r=bholley
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 09 Feb 2016 02:50:16 -0800
changeset 329837 a5daf170c09a2cb138a3edcba915e7b2037cbeae
parent 329836 e0be6880f8e00767529ba5562ae862b7f29d66c2
child 329838 a88ca50a3ed51f8a7592bae17c7cfc16c51b33d9
push id10617
push userdtownsend@mozilla.com
push dateTue, 09 Feb 2016 16:30:19 +0000
reviewersbholley
bugs1141222
milestone47.0a1
Bug 1141222 - Create ScriptError with stack from Cu.reportError. r=bholley
js/xpconnect/src/XPCComponents.cpp
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2289,26 +2289,54 @@ nsXPCComponents_Utils::GetSandbox(nsIXPC
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx)
 {
     // This function shall never fail! Silently eat any failure conditions.
 
     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
-
-    nsCOMPtr<nsIScriptError> scripterr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
-
-    if (!scripterr || !console)
+    if (!console)
         return NS_OK;
 
     const uint64_t innerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx);
 
     RootedObject errorObj(cx, error.isObject() ? &error.toObject() : nullptr);
     JSErrorReport* err = errorObj ? JS_ErrorFromException(cx, errorObj) : nullptr;
+
+    nsCOMPtr<nsIScriptError> scripterr;
+
+    if (errorObj) {
+        JS::RootedObject stackVal(cx, ExceptionStackOrNull(cx, errorObj));
+        if (stackVal) {
+            scripterr = new nsScriptErrorWithStack(stackVal);
+        }
+    }
+
+    nsString fileName;
+    int32_t lineNo = 0;
+
+    if (!scripterr) {
+        nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack();
+        if (frame) {
+            frame->GetFilename(fileName);
+            frame->GetLineNumber(&lineNo);
+            JS::Rooted<JS::Value> stack(cx);
+            nsresult rv = frame->GetNativeSavedFrame(&stack);
+            if (NS_SUCCEEDED(rv) && stack.isObject()) {
+              JS::Rooted<JSObject*> stackObj(cx, &stack.toObject());
+              scripterr = new nsScriptErrorWithStack(stackObj);
+            }
+        }
+    }
+
+    if (!scripterr) {
+        scripterr = new nsScriptError();
+    }
+
     if (err) {
         // It's a proper JS Error
         nsAutoString fileUni;
         CopyUTF8toUTF16(err->filename, fileUni);
 
         uint32_t column = err->uctokenptr - err->uclinebuf;
 
         const char16_t* ucmessage =
@@ -2328,27 +2356,16 @@ nsXPCComponents_Utils::ReportError(Handl
         return NS_OK;
     }
 
     // It's not a JS Error object, so we synthesize as best we're able.
     RootedString msgstr(cx, ToString(cx, error));
     if (!msgstr)
         return NS_OK;
 
-    nsCOMPtr<nsIStackFrame> frame;
-    nsXPConnect* xpc = nsXPConnect::XPConnect();
-    xpc->GetCurrentJSStack(getter_AddRefs(frame));
-
-    nsString fileName;
-    int32_t lineNo = 0;
-    if (frame) {
-        frame->GetFilename(fileName);
-        frame->GetLineNumber(&lineNo);
-    }
-
     nsAutoJSString msg;
     if (!msg.init(cx, msgstr))
         return NS_OK;
 
     nsresult rv = scripterr->InitWithWindowID(
             msg, fileName, EmptyString(), lineNo, 0, 0,
             "XPConnect JavaScript", innerWindowID);
     NS_ENSURE_SUCCESS(rv, NS_OK);