diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties index 007f8534b879..1876af474c75 100644 --- a/dom/locales/en-US/chrome/dom/dom.properties +++ b/dom/locales/en-US/chrome/dom/dom.properties @@ -186,3 +186,5 @@ BadOpaqueRedirectInterceptionWithURL=Failed to load '%S'. A ServiceWorker passed InterceptionCanceledWithURL=Failed to load '%S'. A ServiceWorker canceled the load by calling FetchEvent.preventDefault(). # LOCALIZATION NOTE: Do not translate "ServiceWorker", "promise", or "FetchEvent.respondWith()". %1$S is a URL. %2$S is an error string. InterceptionRejectedResponseWithURL=Failed to load '%1$S'. A ServiceWorker passed a promise to FetchEvent.respondWith() that rejected with '%2$S'. +# LOCALIZATION NOTE: Do not translate "ServiceWorker", "promise", "FetchEvent.respondWith()", or "Response". %1$S is a URL. %2$S is an error string. +InterceptedNonResponseWithURL=Failed to load '%1$S'. A ServiceWorker passed a promise to FetchEvent.respondWith() that resolved with non-Response value '%2$S'. diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index 142e587b55b9..0887bc63d6bc 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -283,6 +283,13 @@ public: mRespondWithColumnNumber, aMessageName, aParams); } + void AsyncLog(const nsACString& aSourceSpec, uint32_t aLine, uint32_t aColumn, + const nsACString& aMessageName, const nsTArray& aParams) + { + ::AsyncLog(mInterceptedChannel, aSourceSpec, aLine, aColumn, aMessageName, + aParams); + } + private: ~RespondWithHandler() { @@ -421,12 +428,17 @@ ExtractErrorValues(JSContext* aCx, JS::Handle aValue, class MOZ_STACK_CLASS AutoCancel { RefPtr mOwner; + nsCString mSourceSpec; + uint32_t mLine; + uint32_t mColumn; nsCString mMessageName; nsTArray mParams; public: AutoCancel(RespondWithHandler* aOwner, const nsString& aRequestURL) : mOwner(aOwner) + , mLine(0) + , mColumn(0) , mMessageName(NS_LITERAL_CSTRING("InterceptionFailedWithURL")) { mParams.AppendElement(aRequestURL); @@ -435,7 +447,11 @@ public: ~AutoCancel() { if (mOwner) { - mOwner->AsyncLog(mMessageName, mParams); + if (mSourceSpec.IsEmpty()) { + mOwner->AsyncLog(mMessageName, mParams); + } else { + mOwner->AsyncLog(mSourceSpec, mLine, mColumn, mMessageName, mParams); + } mOwner->CancelRequest(NS_ERROR_INTERCEPTION_FAILED); } } @@ -451,6 +467,25 @@ public: StringArrayAppender::Append(mParams, sizeof...(Params), aParams...); } + template + void SetCancelMessageAndLocation(const nsACString& aSourceSpec, + uint32_t aLine, uint32_t aColumn, + const nsACString& aMessageName, + Params... aParams) + { + MOZ_ASSERT(mOwner); + MOZ_ASSERT(mMessageName.EqualsLiteral("InterceptionFailedWithURL")); + MOZ_ASSERT(mParams.Length() == 1); + + mSourceSpec = aSourceSpec; + mLine = aLine; + mColumn = aColumn; + + mMessageName = aMessageName; + mParams.Clear(); + StringArrayAppender::Append(mParams, sizeof...(Params), aParams...); + } + void Reset() { mOwner = nullptr; @@ -466,12 +501,31 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle aValu if (!aValue.isObject()) { NS_WARNING("FetchEvent::RespondWith was passed a promise resolved to a non-Object value"); + + nsCString sourceSpec; + uint32_t line = 0; + uint32_t column = 0; + nsString valueString; + ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column, valueString); + + autoCancel.SetCancelMessageAndLocation(sourceSpec, line, column, + NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"), + &mRequestURL, &valueString); return; } RefPtr response; nsresult rv = UNWRAP_OBJECT(Response, &aValue.toObject(), response); if (NS_FAILED(rv)) { + nsCString sourceSpec; + uint32_t line = 0; + uint32_t column = 0; + nsString valueString; + ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column, valueString); + + autoCancel.SetCancelMessageAndLocation(sourceSpec, line, column, + NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"), + &mRequestURL, &valueString); return; }