mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-03 05:47:29 +09:00
Issue #1442 - Part 16 - Report stream errors during consumption. https://bugzilla.mozilla.org/show_bug.cgi?id=1128959
This commit is contained in:
parent
b124e54fc7
commit
529bc13f05
6 changed files with 139 additions and 77 deletions
|
|
@ -39,6 +39,8 @@
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/CustomElementRegistry.h"
|
#include "mozilla/dom/CustomElementRegistry.h"
|
||||||
#include "mozilla/dom/DocumentFragment.h"
|
#include "mozilla/dom/DocumentFragment.h"
|
||||||
|
#include "mozilla/dom/DOMException.h"
|
||||||
|
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||||
#include "mozilla/dom/DOMTypes.h"
|
#include "mozilla/dom/DOMTypes.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/FileSystemSecurity.h"
|
#include "mozilla/dom/FileSystemSecurity.h"
|
||||||
|
|
@ -10081,3 +10083,72 @@ void nsContentUtils::StructuredClone(JSContext* aCx,
|
||||||
nsTArray<RefPtr<MessagePort>> ports = holder.TakeTransferredPorts();
|
nsTArray<RefPtr<MessagePort>> ports = holder.TakeTransferredPorts();
|
||||||
Unused << ports;
|
Unused << ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
RefPtr<xpc::ErrorReport> report = new xpc::ErrorReport();
|
||||||
|
report->Init(err,
|
||||||
|
"<unknown>", // toString result
|
||||||
|
false, // chrome
|
||||||
|
0); // window ID
|
||||||
|
|
||||||
|
if (!report->mFileName.IsEmpty()) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1010,6 +1010,10 @@ public:
|
||||||
|
|
||||||
static bool PrefetchEnabled(nsIDocShell* aDocShell);
|
static bool PrefetchEnabled(nsIDocShell* aDocShell);
|
||||||
|
|
||||||
|
static void ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||||
|
nsACString& aSourceSpecOut, uint32_t *aLineOut,
|
||||||
|
uint32_t *aColumnOut, nsString& aMessageOut);
|
||||||
|
|
||||||
static nsresult CalculateBufferSizeForImage(const uint32_t& aStride,
|
static nsresult CalculateBufferSizeForImage(const uint32_t& aStride,
|
||||||
const mozilla::gfx::IntSize& aImageSize,
|
const mozilla::gfx::IntSize& aImageSize,
|
||||||
const mozilla::gfx::SurfaceFormat& aFormat,
|
const mozilla::gfx::SurfaceFormat& aFormat,
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ public:
|
||||||
// reporting way.
|
// reporting way.
|
||||||
//
|
//
|
||||||
// Exceptions generated when reading from the ReadableStream are directly sent
|
// Exceptions generated when reading from the ReadableStream are directly sent
|
||||||
// to the Console (NOTE FOR THE REVIEWER: this is part of patch 16)
|
// to the Console.
|
||||||
void
|
void
|
||||||
SetBodyUsed(JSContext* aCx, ErrorResult& aRv);
|
SetBodyUsed(JSContext* aCx, ErrorResult& aRv);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
#include "FetchStreamReader.h"
|
#include "FetchStreamReader.h"
|
||||||
#include "InternalResponse.h"
|
#include "InternalResponse.h"
|
||||||
#include "mozilla/dom/PromiseBinding.h"
|
#include "mozilla/dom/PromiseBinding.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsIScriptError.h"
|
||||||
|
#include "nsPIDOMWindow.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
@ -296,8 +299,56 @@ void
|
||||||
FetchStreamReader::RejectedCallback(JSContext* aCx,
|
FetchStreamReader::RejectedCallback(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aValue)
|
JS::Handle<JS::Value> aValue)
|
||||||
{
|
{
|
||||||
|
ReportErrorToConsole(aCx, aValue);
|
||||||
CloseAndRelease(NS_ERROR_FAILURE);
|
CloseAndRelease(NS_ERROR_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FetchStreamReader::ReportErrorToConsole(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aValue)
|
||||||
|
{
|
||||||
|
nsCString sourceSpec;
|
||||||
|
uint32_t line = 0;
|
||||||
|
uint32_t column = 0;
|
||||||
|
nsString valueString;
|
||||||
|
|
||||||
|
nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line,
|
||||||
|
&column, valueString);
|
||||||
|
|
||||||
|
nsTArray<nsString> params;
|
||||||
|
params.AppendElement(valueString);
|
||||||
|
|
||||||
|
RefPtr<ConsoleReportCollector> reporter = new ConsoleReportCollector();
|
||||||
|
reporter->AddConsoleReport(nsIScriptError::errorFlag,
|
||||||
|
NS_LITERAL_CSTRING("ReadableStreamReader.read"),
|
||||||
|
nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
sourceSpec, line, column,
|
||||||
|
NS_LITERAL_CSTRING("ReadableStreamReadingFailed"),
|
||||||
|
params);
|
||||||
|
|
||||||
|
uint64_t innerWindowId = 0;
|
||||||
|
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mGlobal);
|
||||||
|
if (window) {
|
||||||
|
innerWindowId = window->WindowID();
|
||||||
|
}
|
||||||
|
reporter->FlushReportsByWindowId(innerWindowId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||||
|
if (workerPrivate) {
|
||||||
|
innerWindowId = workerPrivate->WindowID();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<Runnable> r = NS_NewRunnableFunction(
|
||||||
|
[reporter, innerWindowId] () {
|
||||||
|
reporter->FlushReportsByWindowId(innerWindowId);
|
||||||
|
});
|
||||||
|
|
||||||
|
workerPrivate->DispatchToMainThread(r.forget());
|
||||||
|
}
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
} // mozilla namespace
|
} // mozilla namespace
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,9 @@ private:
|
||||||
nsresult
|
nsresult
|
||||||
WriteBuffer();
|
WriteBuffer();
|
||||||
|
|
||||||
|
void
|
||||||
|
ReportErrorToConsole(JSContext* aCx, JS::Handle<JS::Value> aValue);
|
||||||
|
|
||||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||||
nsCOMPtr<nsIEventTarget> mOwningEventTarget;
|
nsCOMPtr<nsIEventTarget> mOwningEventTarget;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "ServiceWorkerEvents.h"
|
#include "ServiceWorkerEvents.h"
|
||||||
|
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
#include "nsIConsoleReportCollector.h"
|
#include "nsIConsoleReportCollector.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "nsINetworkInterceptController.h"
|
#include "nsINetworkInterceptController.h"
|
||||||
|
|
@ -30,8 +31,6 @@
|
||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/BodyUtil.h"
|
#include "mozilla/dom/BodyUtil.h"
|
||||||
#include "mozilla/dom/DOMException.h"
|
|
||||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
|
||||||
#include "mozilla/dom/EncodingUtils.h"
|
#include "mozilla/dom/EncodingUtils.h"
|
||||||
#include "mozilla/dom/FetchEventBinding.h"
|
#include "mozilla/dom/FetchEventBinding.h"
|
||||||
#include "mozilla/dom/MessagePort.h"
|
#include "mozilla/dom/MessagePort.h"
|
||||||
|
|
@ -404,76 +403,6 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
|
||||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event));
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void
|
|
||||||
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<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.
|
|
||||||
RefPtr<xpc::ErrorReport> report = new xpc::ErrorReport();
|
|
||||||
report->Init(err,
|
|
||||||
"<unknown>", // toString result
|
|
||||||
false, // chrome
|
|
||||||
0); // window ID
|
|
||||||
|
|
||||||
if (!report->mFileName.IsEmpty()) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS AutoCancel
|
class MOZ_STACK_CLASS AutoCancel
|
||||||
{
|
{
|
||||||
RefPtr<RespondWithHandler> mOwner;
|
RefPtr<RespondWithHandler> mOwner;
|
||||||
|
|
@ -595,7 +524,8 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||||
uint32_t line = 0;
|
uint32_t line = 0;
|
||||||
uint32_t column = 0;
|
uint32_t column = 0;
|
||||||
nsString valueString;
|
nsString valueString;
|
||||||
ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column, valueString);
|
nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
|
||||||
|
valueString);
|
||||||
|
|
||||||
autoCancel.SetCancelMessageAndLocation(sourceSpec, line, column,
|
autoCancel.SetCancelMessageAndLocation(sourceSpec, line, column,
|
||||||
NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"),
|
NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"),
|
||||||
|
|
@ -610,7 +540,8 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||||
uint32_t line = 0;
|
uint32_t line = 0;
|
||||||
uint32_t column = 0;
|
uint32_t column = 0;
|
||||||
nsString valueString;
|
nsString valueString;
|
||||||
ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column, valueString);
|
nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
|
||||||
|
valueString);
|
||||||
|
|
||||||
autoCancel.SetCancelMessageAndLocation(sourceSpec, line, column,
|
autoCancel.SetCancelMessageAndLocation(sourceSpec, line, column,
|
||||||
NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"),
|
NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"),
|
||||||
|
|
@ -758,7 +689,8 @@ RespondWithHandler::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||||
uint32_t column = mRespondWithColumnNumber;
|
uint32_t column = mRespondWithColumnNumber;
|
||||||
nsString valueString;
|
nsString valueString;
|
||||||
|
|
||||||
ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column, valueString);
|
nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
|
||||||
|
valueString);
|
||||||
|
|
||||||
::AsyncLog(mInterceptedChannel, sourceSpec, line, column,
|
::AsyncLog(mInterceptedChannel, sourceSpec, line, column,
|
||||||
NS_LITERAL_CSTRING("InterceptionRejectedResponseWithURL"),
|
NS_LITERAL_CSTRING("InterceptionRejectedResponseWithURL"),
|
||||||
|
|
@ -896,7 +828,8 @@ public:
|
||||||
nsCString spec;
|
nsCString spec;
|
||||||
uint32_t line = 0;
|
uint32_t line = 0;
|
||||||
uint32_t column = 0;
|
uint32_t column = 0;
|
||||||
ExtractErrorValues(aCx, aValue, spec, &line, &column, mRejectValue);
|
nsContentUtils::ExtractErrorValues(aCx, aValue, spec, &line, &column,
|
||||||
|
mRejectValue);
|
||||||
|
|
||||||
// only use the extracted location if we found one
|
// only use the extracted location if we found one
|
||||||
if (!spec.IsEmpty()) {
|
if (!spec.IsEmpty()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue