Bug 1403348: Part 3 - Support plain XPC Exceptions in ExtractErrorValues. r?baku draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 04 Nov 2017 14:07:39 -0700
changeset 693266 79b244b957322e2923f6357ce5dc83c8c21e9e65
parent 693206 4350a326a49805c6138aabd0ed68136498bf97cd
child 693267 38b56436148659a925b442bd3fc3481191926d9d
child 693282 5b9392666ec8918ca1e205257c37922c509a301f
push id87740
push usermaglione.k@gmail.com
push dateSun, 05 Nov 2017 00:21:02 +0000
reviewersbaku
bugs1403348
milestone58.0a1
Bug 1403348: Part 3 - Support plain XPC Exceptions in ExtractErrorValues. r?baku MozReview-Commit-ID: LrnE82vHjK
dom/base/nsContentUtils.cpp
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -10905,30 +10905,65 @@ nsContentUtils::IsOverridingWindowName(c
 {
   return !aName.IsEmpty() &&
     !aName.LowerCaseEqualsLiteral("_blank") &&
     !aName.LowerCaseEqualsLiteral("_top") &&
     !aName.LowerCaseEqualsLiteral("_parent") &&
     !aName.LowerCaseEqualsLiteral("_self");
 }
 
+// Ugly.
+#define EXTRACT_EXN_VALUES(T, ...)                                \
+  ExtractExceptionValues<mozilla::dom::prototypes::id::T,         \
+                         T##Binding::NativeType, T>(__VA_ARGS__)
+
+template <prototypes::ID PrototypeID, class NativeType, typename T>
+static bool
+ExtractExceptionValues(JSContext* aCx,
+                       JS::HandleObject aObj,
+                       nsACString& aSourceSpecOut,
+                       uint32_t* aLineOut,
+                       uint32_t* aColumnOut,
+                       nsString& aMessageOut)
+{
+  RefPtr<T> exn;
+  if (NS_FAILED((UnwrapObject<PrototypeID, NativeType>(aObj, exn)))) {
+    return false;
+  }
+
+  nsAutoString filename;
+  exn->GetFilename(aCx, filename);
+  if (!filename.IsEmpty()) {
+    CopyUTF16toUTF8(filename, aSourceSpecOut);
+    *aLineOut = exn->LineNumber(aCx);
+    *aColumnOut = exn->ColumnNumber();
+  }
+
+  exn->GetName(aMessageOut);
+  aMessageOut.AppendLiteral(": ");
+
+  nsAutoString message;
+  exn->GetMessageMoz(message);
+  aMessageOut.Append(message);
+  return true;
+}
+
 /* static */ void
 nsContentUtils::ExtractErrorValues(JSContext* aCx,
                                    JS::Handle<JS::Value> aValue,
                                    nsACString& aSourceSpecOut,
                                    uint32_t* aLineOut,
                                    uint32_t* aColumnOut,
                                    nsString& aMessageOut)
 {
   MOZ_ASSERT(aLineOut);
   MOZ_ASSERT(aColumnOut);
 
   if (aValue.isObject()) {
     JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
-    RefPtr<dom::DOMException> domException;
 
     // Try to process as an Error object.  Use the file/line/column values
     // from the Error as they will be more specific to the root cause of
     // the problem.
     JSErrorReport* err = obj ? JS_ErrorFromException(aCx, obj) : nullptr;
     if (err) {
       // Use xpc to extract the error message only.  We don't actually send
       // this report anywhere.
@@ -10942,48 +10977,43 @@ nsContentUtils::ExtractErrorValues(JSCon
         CopyUTF16toUTF8(report->mFileName, aSourceSpecOut);
         *aLineOut = report->mLineNumber;
         *aColumnOut = report->mColumn;
       }
       aMessageOut.Assign(report->mErrorMsg);
     }
 
     // Next, try to unwrap the rejection value as a DOMException.
-    else if(NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException))) {
-
-      nsAutoString filename;
-      domException->GetFilename(aCx, filename);
-      if (!filename.IsEmpty()) {
-        CopyUTF16toUTF8(filename, aSourceSpecOut);
-        *aLineOut = domException->LineNumber(aCx);
-        *aColumnOut = domException->ColumnNumber();
-      }
-
-      domException->GetName(aMessageOut);
-      aMessageOut.AppendLiteral(": ");
-
-      nsAutoString message;
-      domException->GetMessageMoz(message);
-      aMessageOut.Append(message);
+    else if (EXTRACT_EXN_VALUES(DOMException, aCx, obj, aSourceSpecOut,
+                                aLineOut, aColumnOut, aMessageOut)) {
+      return;
+    }
+
+    // Next, try to unwrap the rejection value as an XPC Exception.
+    else if (EXTRACT_EXN_VALUES(Exception, aCx, obj, aSourceSpecOut,
+                                aLineOut, aColumnOut, aMessageOut)) {
+      return;
     }
   }
 
   // If we could not unwrap a specific error type, then perform default safe
   // string conversions on primitives.  Objects will result in "[Object]"
   // unfortunately.
   if (aMessageOut.IsEmpty()) {
     nsAutoJSString jsString;
     if (jsString.init(aCx, aValue)) {
       aMessageOut = jsString;
     } else {
       JS_ClearPendingException(aCx);
     }
   }
 }
 
+#undef EXTRACT_EXN_VALUES
+
 /* static */ bool
 nsContentUtils::DevToolsEnabled(JSContext* aCx)
 {
   if (NS_IsMainThread()) {
     return sDevToolsEnabled;
   }
 
   workers::WorkerPrivate* workerPrivate = workers::GetWorkerPrivateFromContext(aCx);