Bug 642419 - Add error reporting for content scripts. r=smaug
authorJosh Matthews <josh@joshmatthews.net>
Fri, 18 Mar 2011 00:08:18 -0400
changeset 69438 fb1ebb23a1e239d9c93bb6eb25460e35161908d0
parent 69437 7fd948de62a6ca78bbbbaaac117bc2a89d102c0e
child 69439 04338898b5ed971d1cdbed608653c20c1a5fba75
push id19974
push usermfinkle@mozilla.com
push dateFri, 13 May 2011 13:09:49 +0000
treeherdermozilla-central@fb1ebb23a1e2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs642419
milestone6.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 642419 - Add error reporting for content scripts. r=smaug
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsFrameMessageManager.h
content/base/src/nsInProcessTabChildGlobal.cpp
dom/ipc/TabChild.cpp
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -44,16 +44,18 @@
 #include "jsapi.h"
 #include "jsarray.h"
 #include "jsinterp.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
 #include "nsIXULRuntime.h"
+#include "nsIScriptError.h"
+#include "nsIConsoleService.h"
 
 static PRBool
 IsChromeProcess()
 {
   nsCOMPtr<nsIXULRuntime> rt = do_GetService("@mozilla.org/xre/runtime;1");
   if (!rt)
     return PR_TRUE;
 
@@ -528,16 +530,63 @@ NS_NewGlobalMessageManager(nsIChromeFram
                                                         nsnull,
                                                         nsnull,
                                                         nsnull,
                                                         PR_TRUE);
   NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
   return CallQueryInterface(mm, aResult);
 }
 
+void
+ContentScriptErrorReporter(JSContext* aCx,
+                           const char* aMessage,
+                           JSErrorReport* aReport)
+{
+  nsresult rv;
+  nsCOMPtr<nsIScriptError> scriptError =
+      do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+  nsAutoString message, filename, line;
+  PRUint32 lineNumber, columnNumber, flags, errorNumber;
+
+  if (aReport) {
+    if (aReport->ucmessage) {
+      message.Assign(reinterpret_cast<const PRUnichar*>(aReport->ucmessage));
+    }
+    filename.AssignWithConversion(aReport->filename);
+    line.Assign(reinterpret_cast<const PRUnichar*>(aReport->uclinebuf));
+    lineNumber = aReport->lineno;
+    columnNumber = aReport->uctokenptr - aReport->uclinebuf;
+    flags = aReport->flags;
+    errorNumber = aReport->errorNumber;
+  } else {
+    lineNumber = columnNumber = errorNumber = 0;
+    flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
+  }
+
+  if (message.IsEmpty()) {
+    message.AssignWithConversion(aMessage);
+  }
+
+  rv = scriptError->Init(message.get(), filename.get(), line.get(),
+                         lineNumber, columnNumber, flags,
+                         "Message manager content script");
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  nsCOMPtr<nsIConsoleService> consoleService =
+      do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+  if (consoleService) {
+    (void) consoleService->LogMessage(scriptError);
+  }
+}
+
 nsDataHashtable<nsStringHashKey, nsFrameScriptExecutorJSObjectHolder*>*
   nsFrameScriptExecutor::sCachedScripts = nsnull;
 nsRefPtr<nsScriptCacheCleaner> nsFrameScriptExecutor::sScriptCacheCleaner;
 
 void
 nsFrameScriptExecutor::DidCreateCx()
 {
   NS_ASSERTION(mCx, "Should have mCx!");
@@ -611,17 +660,17 @@ nsFrameScriptExecutor::LoadFrameScriptIn
     nsContentUtils::ThreadJSContextStack()->Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
       JSObject* global = nsnull;
       mGlobal->GetJSObject(&global);
       if (global) {
-        JS_ExecuteScript(mCx, global, holder->mObject, nsnull);
+        (void) JS_ExecuteScript(mCx, global, holder->mObject, nsnull);
       }
     }
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
     return;
   }
 
   nsCString url = NS_ConvertUTF16toUTF8(aURL);
@@ -679,17 +728,17 @@ nsFrameScriptExecutor::LoadFrameScriptIn
           if (!scheme.EqualsLiteral("data")) {
             nsFrameScriptExecutorJSObjectHolder* holder =
               new nsFrameScriptExecutorJSObjectHolder(scriptObj);
             // Root the object also for caching.
             JS_AddNamedObjectRoot(mCx, &(holder->mObject),
                                   "Cached message manager script");
             sCachedScripts->Put(aURL, holder);
           }
-          JS_ExecuteScript(mCx, global, scriptObj, nsnull);
+          (void) JS_ExecuteScript(mCx, global, scriptObj, nsnull);
         }
         //XXX Argh, JSPrincipals are manually refcounted!
         JSPRINCIPALS_DROP(mCx, jsprin);
       }
     } 
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
   }
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -175,16 +175,21 @@ protected:
   void* mCallbackData;
   JSContext* mContext;
   nsTArray<nsString> mPendingScripts;
 public:
   static nsFrameMessageManager* sParentProcessManager;
   static nsFrameMessageManager* sChildProcessManager;
 };
 
+void
+ContentScriptErrorReporter(JSContext* aCx,
+                           const char* aMessage,
+                           JSErrorReport* aReport);
+
 class nsScriptCacheCleaner;
 
 struct nsFrameScriptExecutorJSObjectHolder
 {
   nsFrameScriptExecutorJSObjectHolder(JSObject* aObject) : mObject(aObject)
   { MOZ_COUNT_CTOR(nsFrameScriptExecutorJSObjectHolder); }
   ~nsFrameScriptExecutorJSObjectHolder()
   { MOZ_COUNT_DTOR(nsFrameScriptExecutorJSObjectHolder); }
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -294,16 +294,17 @@ nsInProcessTabChildGlobal::InitTabChildG
   nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0);
   nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
 
   JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
   JS_SetScriptStackQuota(cx, 25 * sizeof(size_t) * 1024 * 1024);
 
   JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_ANONFUNFIX | JSOPTION_PRIVATE_IS_NSISUPPORTS);
   JS_SetVersion(cx, JSVERSION_LATEST);
+  JS_SetErrorReporter(cx, ContentScriptErrorReporter);
 
   xpc_LocalizeContext(cx);
 
   JSAutoRequest ar(cx);
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
                          /*nsIXPConnect::OMIT_COMPONENTS_OBJECT ?  |*/
                          nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -843,16 +843,17 @@ TabChild::InitTabChildGlobal()
   nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0);
   nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
 
   JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
   JS_SetScriptStackQuota(cx, 25 * sizeof(size_t) * 1024 * 1024);
 
   JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_ANONFUNFIX | JSOPTION_PRIVATE_IS_NSISUPPORTS);
   JS_SetVersion(cx, JSVERSION_LATEST);
+  JS_SetErrorReporter(cx, ContentScriptErrorReporter);
 
   xpc_LocalizeContext(cx);
 
   JSAutoRequest ar(cx);
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
                          /*nsIXPConnect::OMIT_COMPONENTS_OBJECT ?  |*/
                          nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;