diff options
-rw-r--r-- | dom/bindings/nsIScriptError.idl | 15 | ||||
-rw-r--r-- | dom/bindings/nsScriptError.cpp | 177 | ||||
-rw-r--r-- | dom/bindings/nsScriptError.h | 23 | ||||
-rw-r--r-- | js/xpconnect/src/nsXPConnect.cpp | 14 |
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); } |