Bug 1254853 - Add a Helper to Report a ScriptError to the Main Thread. r=khuey
authorBevis Tseng <btseng@mozilla.com>
Wed, 16 Mar 2016 15:12:17 +0800
changeset 290382 e3d7ad16257a6303fed544ae33c139bde8ecaa1b
parent 290381 aaf2b3f9970e9d5e81d6f8d631afe715e2b9f982
child 290383 a1d4844ab73528452d0e1a2186c63fb695bd57ec
push id74233
push userryanvm@gmail.com
push dateFri, 25 Mar 2016 20:04:12 +0000
treeherdermozilla-inbound@f66ab359f3ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs1254853
milestone48.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 1254853 - Add a Helper to Report a ScriptError to the Main Thread. r=khuey
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/ScriptErrorHelper.cpp
dom/indexedDB/ScriptErrorHelper.h
dom/indexedDB/moz.build
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -34,26 +34,25 @@
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/dom/ipc/BlobChild.h"
 #include "mozilla/dom/ipc/nsIRemoteBlob.h"
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/ipc/FileDescriptor.h"
 #include "mozilla/ipc/InputStreamParams.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "nsCOMPtr.h"
-#include "nsContentUtils.h"
-#include "nsIConsoleService.h"
 #include "nsIDocument.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 #include "nsISupportsPrimitives.h"
 #include "nsThreadUtils.h"
 #include "ProfilerHelpers.h"
 #include "ReportInternalError.h"
+#include "ScriptErrorHelper.h"
 #include "nsQueryObject.h"
 
 // Include this last to avoid path problems on Windows.
 #include "ActorsChild.h"
 
 namespace mozilla {
 namespace dom {
 
@@ -127,60 +126,16 @@ private:
 #ifdef DEBUG
     mDatabase = nullptr;
 #endif
   }
 };
 
 } // namespace
 
-class IDBDatabase::LogWarningRunnable final
-  : public nsRunnable
-{
-  nsCString mMessageName;
-  nsString mFilename;
-  uint32_t mLineNumber;
-  uint32_t mColumnNumber;
-  uint64_t mInnerWindowID;
-  bool mIsChrome;
-
-public:
-  LogWarningRunnable(const char* aMessageName,
-                     const nsAString& aFilename,
-                     uint32_t aLineNumber,
-                     uint32_t aColumnNumber,
-                     bool aIsChrome,
-                     uint64_t aInnerWindowID)
-    : mMessageName(aMessageName)
-    , mFilename(aFilename)
-    , mLineNumber(aLineNumber)
-    , mColumnNumber(aColumnNumber)
-    , mInnerWindowID(aInnerWindowID)
-    , mIsChrome(aIsChrome)
-  {
-    MOZ_ASSERT(!NS_IsMainThread());
-  }
-
-  static void
-  LogWarning(const char* aMessageName,
-             const nsAString& aFilename,
-             uint32_t aLineNumber,
-             uint32_t aColumnNumber,
-             bool aIsChrome,
-             uint64_t aInnerWindowID);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-private:
-  ~LogWarningRunnable()
-  { }
-
-  NS_DECL_NSIRUNNABLE
-};
-
 class IDBDatabase::Observer final
   : public nsIObserver
 {
   IDBDatabase* mWeakDatabase;
   const uint64_t mWindowId;
 
 public:
   Observer(IDBDatabase* aDatabase, uint64_t aWindowId)
@@ -1252,33 +1207,23 @@ void
 IDBDatabase::LogWarning(const char* aMessageName,
                         const nsAString& aFilename,
                         uint32_t aLineNumber,
                         uint32_t aColumnNumber)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aMessageName);
 
-  if (NS_IsMainThread()) {
-    LogWarningRunnable::LogWarning(aMessageName,
-                                   aFilename,
-                                   aLineNumber,
-                                   aColumnNumber,
-                                   mFactory->IsChrome(),
-                                   mFactory->InnerWindowID());
-  } else {
-    RefPtr<LogWarningRunnable> runnable =
-      new LogWarningRunnable(aMessageName,
-                             aFilename,
-                             aLineNumber,
-                             aColumnNumber,
-                             mFactory->IsChrome(),
-                             mFactory->InnerWindowID());
-    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
-  }
+  ScriptErrorHelper::DumpLocalizedMessage(nsDependentCString(aMessageName),
+                                          aFilename,
+                                          aLineNumber,
+                                          aColumnNumber,
+                                          nsIScriptError::warningFlag,
+                                          mFactory->IsChrome(),
+                                          mFactory->InnerWindowID());
 }
 
 NS_IMPL_ADDREF_INHERITED(IDBDatabase, IDBWrapperCache)
 NS_IMPL_RELEASE_INHERITED(IDBDatabase, IDBWrapperCache)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase)
 NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
 
@@ -1351,95 +1296,16 @@ CancelableRunnableWrapper::Cancel()
   if (mRunnable) {
     mRunnable = nullptr;
     return NS_OK;
   }
 
   return NS_ERROR_UNEXPECTED;
 }
 
-// static
-void
-IDBDatabase::
-LogWarningRunnable::LogWarning(const char* aMessageName,
-                               const nsAString& aFilename,
-                               uint32_t aLineNumber,
-                               uint32_t aColumnNumber,
-                               bool aIsChrome,
-                               uint64_t aInnerWindowID)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aMessageName);
-
-  nsXPIDLString localizedMessage;
-  if (NS_WARN_IF(NS_FAILED(
-    nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
-                                       aMessageName,
-                                       localizedMessage)))) {
-    return;
-  }
-
-  nsAutoCString category;
-  if (aIsChrome) {
-    category.AssignLiteral("chrome ");
-  } else {
-    category.AssignLiteral("content ");
-  }
-  category.AppendLiteral("javascript");
-
-  nsCOMPtr<nsIConsoleService> consoleService =
-    do_GetService(NS_CONSOLESERVICE_CONTRACTID);
-  MOZ_ASSERT(consoleService);
-
-  nsCOMPtr<nsIScriptError> scriptError =
-    do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
-  MOZ_ASSERT(consoleService);
-
-  if (aInnerWindowID) {
-    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-      scriptError->InitWithWindowID(localizedMessage,
-                                    aFilename,
-                                    /* aSourceLine */ EmptyString(),
-                                    aLineNumber,
-                                    aColumnNumber,
-                                    nsIScriptError::warningFlag,
-                                    category,
-                                    aInnerWindowID)));
-  } else {
-    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-      scriptError->Init(localizedMessage,
-                        aFilename,
-                        /* aSourceLine */ EmptyString(),
-                        aLineNumber,
-                        aColumnNumber,
-                        nsIScriptError::warningFlag,
-                        category.get())));
-  }
-
-  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(consoleService->LogMessage(scriptError)));
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(IDBDatabase::LogWarningRunnable, nsRunnable)
-
-NS_IMETHODIMP
-IDBDatabase::
-LogWarningRunnable::Run()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  LogWarning(mMessageName.get(),
-             mFilename,
-             mLineNumber,
-             mColumnNumber,
-             mIsChrome,
-             mInnerWindowID);
-
-  return NS_OK;
-}
-
 NS_IMPL_ISUPPORTS(IDBDatabase::Observer, nsIObserver)
 
 NS_IMETHODIMP
 IDBDatabase::
 Observer::Observe(nsISupports* aSubject,
                   const char* aTopic,
                   const char16_t* aData)
 {
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -48,19 +48,16 @@ class PBackgroundIDBDatabaseFileChild;
 
 class IDBDatabase final
   : public IDBWrapperCache
 {
   typedef mozilla::dom::indexedDB::DatabaseSpec DatabaseSpec;
   typedef mozilla::dom::StorageType StorageType;
   typedef mozilla::dom::quota::PersistenceType PersistenceType;
 
-  class LogWarningRunnable;
-  friend class LogWarningRunnable;
-
   class Observer;
   friend class Observer;
 
   // The factory must be kept alive when IndexedDB is used in multiple
   // processes. If it dies then the entire actor tree will be destroyed with it
   // and the world will explode.
   RefPtr<IDBFactory> mFactory;
 
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -36,16 +36,17 @@
 
 #include "FileInfo.h"
 #include "FileManager.h"
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IDBKeyRange.h"
 #include "IDBRequest.h"
 #include "ProfilerHelpers.h"
+#include "ScriptErrorHelper.h"
 #include "WorkerScope.h"
 #include "WorkerPrivate.h"
 
 // Bindings for ResolveConstructors
 #include "mozilla/dom/IDBCursorBinding.h"
 #include "mozilla/dom/IDBDatabaseBinding.h"
 #include "mozilla/dom/IDBFactoryBinding.h"
 #include "mozilla/dom/IDBIndexBinding.h"
@@ -533,55 +534,24 @@ IndexedDatabaseManager::CommonPostHandle
       status = nsEventStatus_eIgnore;
     }
   }
 
   if (status == nsEventStatus_eConsumeNoDefault) {
     return NS_OK;
   }
 
-  nsAutoCString category;
-  if (aFactory->IsChrome()) {
-    category.AssignLiteral("chrome ");
-  } else {
-    category.AssignLiteral("content ");
-  }
-  category.AppendLiteral("javascript");
-
   // Log the error to the error console.
-  nsCOMPtr<nsIConsoleService> consoleService =
-    do_GetService(NS_CONSOLESERVICE_CONTRACTID);
-  MOZ_ASSERT(consoleService);
-
-  nsCOMPtr<nsIScriptError> scriptError =
-    do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
-  MOZ_ASSERT(consoleService);
-
-  if (uint64_t innerWindowID = aFactory->InnerWindowID()) {
-    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-      scriptError->InitWithWindowID(errorName,
-                                    init.mFilename,
-                                    /* aSourceLine */ EmptyString(),
-                                    init.mLineno,
-                                    init.mColno,
-                                    nsIScriptError::errorFlag,
-                                    category,
-                                    innerWindowID)));
-  } else {
-    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-      scriptError->Init(errorName,
-                        init.mFilename,
-                        /* aSourceLine */ EmptyString(),
-                        init.mLineno,
-                        init.mColno,
-                        nsIScriptError::errorFlag,
-                        category.get())));
-  }
-
-  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(consoleService->LogMessage(scriptError)));
+  ScriptErrorHelper::Dump(errorName,
+                          init.mFilename,
+                          init.mLineno,
+                          init.mColno,
+                          nsIScriptError::errorFlag,
+                          aFactory->IsChrome(),
+                          aFactory->InnerWindowID());
 
   return NS_OK;
 }
 
 // static
 bool
 IndexedDatabaseManager::DefineIndexedDB(JSContext* aCx,
                                         JS::Handle<JSObject*> aGlobal)
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/ScriptErrorHelper.cpp
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ScriptErrorHelper.h"
+
+#include "MainThreadUtils.h"
+#include "nsCOMPtr.h"
+#include "nsContentUtils.h"
+#include "nsIConsoleService.h"
+#include "nsIScriptError.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+
+namespace {
+
+class ScriptErrorRunnable final : public nsRunnable
+{
+  nsString mMessage;
+  nsCString mMessageName;
+  nsString mFilename;
+  uint32_t mLineNumber;
+  uint32_t mColumnNumber;
+  uint32_t mSeverityFlag;
+  uint64_t mInnerWindowID;
+  bool mIsChrome;
+
+public:
+  ScriptErrorRunnable(const nsAString& aMessage,
+                      const nsAString& aFilename,
+                      uint32_t aLineNumber,
+                      uint32_t aColumnNumber,
+                      uint32_t aSeverityFlag,
+                      bool aIsChrome,
+                      uint64_t aInnerWindowID)
+    : mMessage(aMessage)
+    , mFilename(aFilename)
+    , mLineNumber(aLineNumber)
+    , mColumnNumber(aColumnNumber)
+    , mSeverityFlag(aSeverityFlag)
+    , mInnerWindowID(aInnerWindowID)
+    , mIsChrome(aIsChrome)
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+    mMessageName.SetIsVoid(true);
+  }
+
+  ScriptErrorRunnable(const nsACString& aMessageName,
+                      const nsAString& aFilename,
+                      uint32_t aLineNumber,
+                      uint32_t aColumnNumber,
+                      uint32_t aSeverityFlag,
+                      bool aIsChrome,
+                      uint64_t aInnerWindowID)
+    : mMessageName(aMessageName)
+    , mFilename(aFilename)
+    , mLineNumber(aLineNumber)
+    , mColumnNumber(aColumnNumber)
+    , mSeverityFlag(aSeverityFlag)
+    , mInnerWindowID(aInnerWindowID)
+    , mIsChrome(aIsChrome)
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+    mMessage.SetIsVoid(true);
+  }
+
+  static void
+  DumpLocalizedMessage(const nsCString& aMessageName,
+                       const nsAString& aFilename,
+                       uint32_t aLineNumber,
+                       uint32_t aColumnNumber,
+                       uint32_t aSeverityFlag,
+                       bool aIsChrome,
+                       uint64_t aInnerWindowID)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(!aMessageName.IsEmpty());
+
+    nsXPIDLString localizedMessage;
+    if (NS_WARN_IF(NS_FAILED(
+      nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+                                         aMessageName.get(),
+                                         localizedMessage)))) {
+      return;
+    }
+
+    Dump(localizedMessage,
+         aFilename,
+         aLineNumber,
+         aColumnNumber,
+         aSeverityFlag,
+         aIsChrome,
+         aInnerWindowID);
+  }
+
+  static void
+  Dump(const nsAString& aMessage,
+       const nsAString& aFilename,
+       uint32_t aLineNumber,
+       uint32_t aColumnNumber,
+       uint32_t aSeverityFlag,
+       bool aIsChrome,
+       uint64_t aInnerWindowID)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    nsAutoCString category;
+    if (aIsChrome) {
+      category.AssignLiteral("chrome ");
+    } else {
+      category.AssignLiteral("content ");
+    }
+    category.AppendLiteral("javascript");
+
+    nsCOMPtr<nsIConsoleService> consoleService =
+      do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+    MOZ_ASSERT(consoleService);
+
+    nsCOMPtr<nsIScriptError> scriptError =
+      do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
+    MOZ_ASSERT(scriptError);
+
+    if (aInnerWindowID) {
+      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+        scriptError->InitWithWindowID(aMessage,
+                                      aFilename,
+                                      /* aSourceLine */ EmptyString(),
+                                      aLineNumber,
+                                      aColumnNumber,
+                                      aSeverityFlag,
+                                      category,
+                                      aInnerWindowID)));
+    } else {
+      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+        scriptError->Init(aMessage,
+                          aFilename,
+                          /* aSourceLine */ EmptyString(),
+                          aLineNumber,
+                          aColumnNumber,
+                          aSeverityFlag,
+                          category.get())));
+    }
+
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(consoleService->LogMessage(scriptError)));
+  }
+
+  NS_IMETHOD
+  Run() override
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(mMessage.IsVoid() != mMessageName.IsVoid());
+
+    if (!mMessage.IsVoid()) {
+      Dump(mMessage,
+           mFilename,
+           mLineNumber,
+           mColumnNumber,
+           mSeverityFlag,
+           mIsChrome,
+           mInnerWindowID);
+      return NS_OK;
+    }
+
+    DumpLocalizedMessage(mMessageName,
+                         mFilename,
+                         mLineNumber,
+                         mColumnNumber,
+                         mSeverityFlag,
+                         mIsChrome,
+                         mInnerWindowID);
+
+    return NS_OK;
+  }
+
+private:
+  virtual ~ScriptErrorRunnable() {}
+};
+
+} // namespace
+
+namespace mozilla {
+namespace dom {
+namespace indexedDB {
+
+/*static*/ void
+ScriptErrorHelper::Dump(const nsAString& aMessage,
+                        const nsAString& aFilename,
+                        uint32_t aLineNumber,
+                        uint32_t aColumnNumber,
+                        uint32_t aSeverityFlag,
+                        bool aIsChrome,
+                        uint64_t aInnerWindowID)
+{
+  if (NS_IsMainThread()) {
+    ScriptErrorRunnable::Dump(aMessage,
+                              aFilename,
+                              aLineNumber,
+                              aColumnNumber,
+                              aSeverityFlag,
+                              aIsChrome,
+                              aInnerWindowID);
+  } else {
+    RefPtr<ScriptErrorRunnable> runnable =
+      new ScriptErrorRunnable(aMessage,
+                              aFilename,
+                              aLineNumber,
+                              aColumnNumber,
+                              aSeverityFlag,
+                              aIsChrome,
+                              aInnerWindowID);
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
+  }
+}
+
+/*static*/ void
+ScriptErrorHelper::DumpLocalizedMessage(const nsACString& aMessageName,
+                                        const nsAString& aFilename,
+                                        uint32_t aLineNumber,
+                                        uint32_t aColumnNumber,
+                                        uint32_t aSeverityFlag,
+                                        bool aIsChrome,
+                                        uint64_t aInnerWindowID)
+{
+  if (NS_IsMainThread()) {
+    ScriptErrorRunnable::DumpLocalizedMessage(nsAutoCString(aMessageName),
+                                              aFilename,
+                                              aLineNumber,
+                                              aColumnNumber,
+                                              aSeverityFlag,
+                                              aIsChrome,
+                                              aInnerWindowID);
+  } else {
+    RefPtr<ScriptErrorRunnable> runnable =
+      new ScriptErrorRunnable(aMessageName,
+                              aFilename,
+                              aLineNumber,
+                              aColumnNumber,
+                              aSeverityFlag,
+                              aIsChrome,
+                              aInnerWindowID);
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
+  }
+}
+
+} // namespace indexedDB
+} // namespace dom
+} // namespace mozilla
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/ScriptErrorHelper.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_indexeddb_scripterrorhelper_h__
+#define mozilla_dom_indexeddb_scripterrorhelper_h__
+
+class nsAString;
+
+namespace mozilla {
+namespace dom {
+namespace indexedDB {
+
+// Helper to report a script error to the main thread.
+class ScriptErrorHelper
+{
+public:
+  static void Dump(const nsAString& aMessage,
+                   const nsAString& aFilename,
+                   uint32_t aLineNumber,
+                   uint32_t aColumnNumber,
+                   uint32_t aSeverityFlag, /* nsIScriptError::xxxFlag */
+                   bool aIsChrome,
+                   uint64_t aInnerWindowID);
+
+  static void DumpLocalizedMessage(const nsACString& aMessageName,
+                                   const nsAString& aFilename,
+                                   uint32_t aLineNumber,
+                                   uint32_t aColumnNumber,
+                                   uint32_t aSeverityFlag, /* nsIScriptError::xxxFlag */
+                                   bool aIsChrome,
+                                   uint64_t aInnerWindowID);
+};
+
+} // namespace indexedDB
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_indexeddb_scripterrorhelper_h__
\ No newline at end of file
--- a/dom/indexedDB/moz.build
+++ b/dom/indexedDB/moz.build
@@ -62,16 +62,17 @@ UNIFIED_SOURCES += [
     'IDBObjectStore.cpp',
     'IDBRequest.cpp',
     'IDBTransaction.cpp',
     'IDBWrapperCache.cpp',
     'IndexedDatabaseManager.cpp',
     'KeyPath.cpp',
     'PermissionRequestBase.cpp',
     'ReportInternalError.cpp',
+    'ScriptErrorHelper.cpp',
 ]
 
 SOURCES += [
     'ActorsParent.cpp', # This file is huge.
     'Key.cpp', # We disable a warning on this file only
 ]
 
 IPDL_SOURCES += [