summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dom/bindings/nsIScriptError.idl15
-rw-r--r--dom/bindings/nsScriptError.cpp177
-rw-r--r--dom/bindings/nsScriptError.h23
-rw-r--r--js/xpconnect/src/nsXPConnect.cpp14
4 files changed, 184 insertions, 45 deletions
diff --git a/dom/bindings/nsIScriptError.idl b/dom/bindings/nsIScriptError.idl
index 468ca682f..8436361a8 100644
--- a/dom/bindings/nsIScriptError.idl
+++ b/dom/bindings/nsIScriptError.idl
@@ -9,13 +9,25 @@
#include "nsISupports.idl"
+#include "nsIArray.idl"
#include "nsIConsoleMessage.idl"
%{C++
#include "nsStringGlue.h" // for nsDependentCString
%}
-[scriptable, uuid(361be358-76f0-47aa-b37b-6ad833599e8d)]
+[scriptable, uuid(e8933fc9-c302-4e12-a55b-4f88611d9c6c)]
+interface nsIScriptErrorNote : nsISupports
+{
+ readonly attribute AString errorMessage;
+ readonly attribute AString sourceName;
+ readonly attribute uint32_t lineNumber;
+ readonly attribute uint32_t columnNumber;
+
+ AUTF8String toString();
+};
+
+[scriptable, uuid(63eb4d3e-7d99-4150-b4f3-11314f9d82a9)]
interface nsIScriptError : nsIConsoleMessage
{
/** pseudo-flag for default case */
@@ -74,6 +86,7 @@ interface nsIScriptError : nsIConsoleMessage
*/
attribute AString errorMessageName;
+ readonly attribute nsIArray notes;
void init(in AString message,
in AString sourceName,
diff --git a/dom/bindings/nsScriptError.cpp b/dom/bindings/nsScriptError.cpp
index 686b0f7fc..9248d1a31 100644
--- a/dom/bindings/nsScriptError.cpp
+++ b/dom/bindings/nsScriptError.cpp
@@ -17,6 +17,7 @@
#include "nsPIDOMWindow.h"
#include "nsILoadContext.h"
#include "nsIDocShell.h"
+#include "nsIMutableArray.h"
#include "nsIScriptError.h"
#include "nsISensitiveInfoHiddenURI.h"
@@ -47,6 +48,12 @@ nsScriptErrorBase::nsScriptErrorBase()
nsScriptErrorBase::~nsScriptErrorBase() {}
void
+nsScriptErrorBase::AddNote(nsIScriptErrorNote* note)
+{
+ mNotes.AppendObject(note);
+}
+
+void
nsScriptErrorBase::InitializeOnMainThread()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -189,6 +196,28 @@ nsScriptErrorBase::Init(const nsAString& message,
0);
}
+static void
+AssignSourceNameHelper(nsString& aSourceNameDest, const nsAString& aSourceNameSrc)
+{
+ if (aSourceNameSrc.IsEmpty())
+ return;
+
+ aSourceNameDest.Assign(aSourceNameSrc);
+
+ nsCOMPtr<nsIURI> uri;
+ nsAutoCString pass;
+ if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), aSourceNameSrc)) &&
+ NS_SUCCEEDED(uri->GetPassword(pass)) &&
+ !pass.IsEmpty())
+ {
+ nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri = do_QueryInterface(uri);
+
+ nsAutoCString loc;
+ if (safeUri && NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc)))
+ aSourceNameDest.Assign(NS_ConvertUTF8toUTF16(loc));
+ }
+}
+
NS_IMETHODIMP
nsScriptErrorBase::InitWithWindowID(const nsAString& message,
const nsAString& sourceName,
@@ -200,26 +229,7 @@ nsScriptErrorBase::InitWithWindowID(const nsAString& message,
uint64_t aInnerWindowID)
{
mMessage.Assign(message);
-
- if (!sourceName.IsEmpty()) {
- mSourceName.Assign(sourceName);
-
- nsCOMPtr<nsIURI> uri;
- nsAutoCString pass;
- if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), sourceName)) &&
- NS_SUCCEEDED(uri->GetPassword(pass)) &&
- !pass.IsEmpty()) {
- nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri =
- do_QueryInterface(uri);
-
- nsAutoCString loc;
- if (safeUri &&
- NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc))) {
- mSourceName.Assign(NS_ConvertUTF8toUTF16(loc));
- }
- }
- }
-
+ AssignSourceNameHelper(mSourceName, sourceName);
mLineNumber = lineNumber;
mSourceLine.Assign(sourceLine);
mColumnNumber = columnNumber;
@@ -235,8 +245,11 @@ nsScriptErrorBase::InitWithWindowID(const nsAString& message,
return NS_OK;
}
-NS_IMETHODIMP
-nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
+static nsresult
+ToStringHelper(const char* aSeverity, const nsString& aMessage,
+ const nsString& aSourceName, const nsString* aSourceLine,
+ uint32_t aLineNumber, uint32_t aColumnNumber,
+ nsACString& /*UTF8*/ aResult)
{
static const char format0[] =
"[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]";
@@ -245,43 +258,39 @@ nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
static const char format2[] =
"[%s: \"%s\"]";
- static const char error[] = "JavaScript Error";
- static const char warning[] = "JavaScript Warning";
-
- const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning;
-
char* temp;
char* tempMessage = nullptr;
char* tempSourceName = nullptr;
char* tempSourceLine = nullptr;
- if (!mMessage.IsEmpty())
- tempMessage = ToNewUTF8String(mMessage);
- if (!mSourceName.IsEmpty())
+ if (!aMessage.IsEmpty())
+ tempMessage = ToNewUTF8String(aMessage);
+ if (!aSourceName.IsEmpty())
// Use at most 512 characters from mSourceName.
- tempSourceName = ToNewUTF8String(StringHead(mSourceName, 512));
- if (!mSourceLine.IsEmpty())
+ tempSourceName = ToNewUTF8String(StringHead(aSourceName, 512));
+ if (aSourceLine && !aSourceLine->IsEmpty())
// Use at most 512 characters from mSourceLine.
- tempSourceLine = ToNewUTF8String(StringHead(mSourceLine, 512));
+ tempSourceLine = ToNewUTF8String(StringHead(*aSourceLine, 512));
- if (nullptr != tempSourceName && nullptr != tempSourceLine)
+ if (nullptr != tempSourceName && nullptr != tempSourceLine) {
temp = JS_smprintf(format0,
- severity,
+ aSeverity,
tempMessage,
tempSourceName,
- mLineNumber,
- mColumnNumber,
+ aLineNumber,
+ aColumnNumber,
tempSourceLine);
- else if (!mSourceName.IsEmpty())
+ } else if (!aSourceName.IsEmpty()) {
temp = JS_smprintf(format1,
- severity,
+ aSeverity,
tempMessage,
tempSourceName,
- mLineNumber);
- else
+ aLineNumber);
+ } else {
temp = JS_smprintf(format2,
- severity,
+ aSeverity,
tempMessage);
+ }
if (nullptr != tempMessage)
free(tempMessage);
@@ -299,6 +308,18 @@ nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
}
NS_IMETHODIMP
+nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult)
+{
+ static const char error[] = "JavaScript Error";
+ static const char warning[] = "JavaScript Warning";
+
+ const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning;
+
+ return ToStringHelper(severity, mMessage, mSourceName, &mSourceLine,
+ mLineNumber, mColumnNumber, aResult);
+}
+
+NS_IMETHODIMP
nsScriptErrorBase::GetOuterWindowID(uint64_t* aOuterWindowID)
{
NS_WARNING_ASSERTION(NS_IsMainThread() || mInitializedOnMainThread,
@@ -342,4 +363,76 @@ nsScriptErrorBase::GetIsFromPrivateWindow(bool* aIsFromPrivateWindow)
return NS_OK;
}
+NS_IMETHODIMP
+nsScriptErrorBase::GetNotes(nsIArray** aNotes)
+{
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMutableArray> array =
+ do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t len = mNotes.Length();
+ for (uint32_t i = 0; i < len; i++)
+ array->AppendElement(mNotes[i], false);
+ array.forget(aNotes);
+
+ return NS_OK;
+}
+
NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError)
+
+nsScriptErrorNote::nsScriptErrorNote()
+ : mMessage(),
+ mSourceName(),
+ mLineNumber(0),
+ mColumnNumber(0)
+{
+}
+
+nsScriptErrorNote::~nsScriptErrorNote() {}
+
+void
+nsScriptErrorNote::Init(const nsAString& message,
+ const nsAString& sourceName,
+ uint32_t lineNumber,
+ uint32_t columnNumber)
+{
+ mMessage.Assign(message);
+ AssignSourceNameHelper(mSourceName, sourceName);
+ mLineNumber = lineNumber;
+ mColumnNumber = columnNumber;
+}
+
+// nsIScriptErrorNote methods
+NS_IMETHODIMP
+nsScriptErrorNote::GetErrorMessage(nsAString& aResult) {
+ aResult.Assign(mMessage);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptErrorNote::GetSourceName(nsAString& aResult) {
+ aResult.Assign(mSourceName);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptErrorNote::GetLineNumber(uint32_t* result) {
+ *result = mLineNumber;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptErrorNote::GetColumnNumber(uint32_t* result) {
+ *result = mColumnNumber;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptErrorNote::ToString(nsACString& /*UTF8*/ aResult)
+{
+ return ToStringHelper("JavaScript Note", mMessage, mSourceName, nullptr,
+ mLineNumber, mColumnNumber, aResult);
+}
+
+NS_IMPL_ISUPPORTS(nsScriptErrorNote, nsIScriptErrorNote)
diff --git a/dom/bindings/nsScriptError.h b/dom/bindings/nsScriptError.h
index da59e3082..b8049d0a0 100644
--- a/dom/bindings/nsScriptError.h
+++ b/dom/bindings/nsScriptError.h
@@ -17,6 +17,26 @@
#include "nsIScriptError.h"
#include "nsString.h"
+class nsScriptErrorNote final : public nsIScriptErrorNote {
+ public:
+ nsScriptErrorNote();
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSISCRIPTERRORNOTE
+
+ void Init(const nsAString& message, const nsAString& sourceName,
+ uint32_t lineNumber, uint32_t columnNumber);
+
+ private:
+ virtual ~nsScriptErrorNote();
+
+ nsString mMessage;
+ nsString mSourceName;
+ nsString mSourceLine;
+ uint32_t mLineNumber;
+ uint32_t mColumnNumber;
+};
+
// Definition of nsScriptError..
class nsScriptErrorBase : public nsIScriptError {
public:
@@ -25,12 +45,15 @@ public:
NS_DECL_NSICONSOLEMESSAGE
NS_DECL_NSISCRIPTERROR
+ void AddNote(nsIScriptErrorNote* note);
+
protected:
virtual ~nsScriptErrorBase();
void
InitializeOnMainThread();
+ nsCOMArray<nsIScriptErrorNote> mNotes;
nsString mMessage;
nsString mMessageName;
nsString mSourceName;
diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp
index 8102d4a4a..0d1a6be0a 100644
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -326,8 +326,9 @@ xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack)
// mechanisms.
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ NS_ENSURE_TRUE_VOID(consoleService);
- nsCOMPtr<nsIScriptError> errorObject;
+ RefPtr<nsScriptErrorBase> errorObject;
if (mWindowID && aStack) {
// Only set stack on messages related to a document
// As we cache messages in the console service,
@@ -338,12 +339,21 @@ xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack)
errorObject = new nsScriptError();
}
errorObject->SetErrorMessageName(mErrorMsgName);
- NS_ENSURE_TRUE_VOID(consoleService);
nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName, mSourceLine,
mLineNumber, mColumn, mFlags,
mCategory, mWindowID);
NS_ENSURE_SUCCESS_VOID(rv);
+
+ for (size_t i = 0, len = mNotes.Length(); i < len; i++) {
+ ErrorNote& note = mNotes[i];
+
+ nsScriptErrorNote* noteObject = new nsScriptErrorNote();
+ noteObject->Init(note.mErrorMsg, note.mFileName,
+ note.mLineNumber, note.mColumn);
+ errorObject->AddNote(noteObject);
+ }
+
consoleService->LogMessage(errorObject);
}