mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 01:08:39 +09:00
Bug 1288768 - Better error reporting for network errors in workers
This commit is contained in:
parent
8f4e22e819
commit
12f3d0302c
5 changed files with 132 additions and 26 deletions
|
|
@ -495,6 +495,82 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class ReportCompileErrorRunnable final : public WorkerRunnable
|
||||
{
|
||||
public:
|
||||
static void
|
||||
CreateAndDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<ReportCompileErrorRunnable> runnable =
|
||||
new ReportCompileErrorRunnable(aCx, aWorkerPrivate);
|
||||
runnable->Dispatch();
|
||||
}
|
||||
|
||||
private:
|
||||
ReportCompileErrorRunnable(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
void
|
||||
PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// Dispatch may fail if the worker was canceled, no need to report that as
|
||||
// an error, so don't call base class PostDispatch.
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
if (aWorkerPrivate->IsFrozen() ||
|
||||
aWorkerPrivate->IsParentWindowPaused()) {
|
||||
MOZ_ASSERT(!IsDebuggerRunnable());
|
||||
aWorkerPrivate->QueueRunnable(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsSharedWorker()) {
|
||||
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, EmptyString(),
|
||||
EmptyString(),
|
||||
EmptyString(), 0, 0,
|
||||
JSREPORT_ERROR,
|
||||
/* isErrorEvent */ false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsServiceWorker()) {
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
|
||||
aWorkerPrivate->WorkerName(),
|
||||
aWorkerPrivate->ScriptURL(),
|
||||
EmptyString(), EmptyString(), EmptyString(),
|
||||
0, 0, JSREPORT_ERROR, JSEXN_ERR);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aWorkerPrivate->IsAcceptingEvents()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<Event> event =
|
||||
Event::Constructor(aWorkerPrivate, NS_LITERAL_STRING("error"),
|
||||
EventInit());
|
||||
event->SetTrusted(true);
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
aWorkerPrivate->DispatchDOMEvent(nullptr, event, nullptr, &status);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CompileScriptRunnable final : public WorkerRunnable
|
||||
{
|
||||
nsString mScriptURL;
|
||||
|
|
@ -538,9 +614,15 @@ private:
|
|||
}
|
||||
|
||||
// Make sure to propagate exceptions from rv onto aCx, so that they will get
|
||||
// reported after we return. We do this for all failures on rv, because now
|
||||
// we're using rv to track all the state we care about.
|
||||
//
|
||||
// reported after we return. We want to propagate just JS exceptions,
|
||||
// because all the other errors are handled when the script is loaded.
|
||||
// See: https://dom.spec.whatwg.org/#concept-event-fire
|
||||
if (rv.Failed() && !rv.IsJSException()) {
|
||||
ReportCompileErrorRunnable::CreateAndDispatch(aCx, aWorkerPrivate);
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is a little dumb, but aCx is in the null compartment here because we
|
||||
// set it up that way in our Run(), since we had not created the global at
|
||||
// that point yet. So we need to enter the compartment of our global,
|
||||
|
|
@ -1171,7 +1253,8 @@ private:
|
|||
if (aWorkerPrivate->IsSharedWorker()) {
|
||||
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename,
|
||||
mLine, mLineNumber,
|
||||
mColumnNumber, mFlags);
|
||||
mColumnNumber, mFlags,
|
||||
/* isErrorEvent */ true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3250,7 +3333,8 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
|
|||
const nsAString& aLine,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
uint32_t aFlags)
|
||||
uint32_t aFlags,
|
||||
bool aIsErrorEvent)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
|
|
@ -3281,31 +3365,42 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
|
|||
// May be null.
|
||||
nsPIDOMWindowInner* window = sharedWorker->GetOwner();
|
||||
|
||||
RootedDictionary<ErrorEventInit> errorInit(aCx);
|
||||
errorInit.mBubbles = false;
|
||||
errorInit.mCancelable = true;
|
||||
errorInit.mMessage = aMessage;
|
||||
errorInit.mFilename = aFilename;
|
||||
errorInit.mLineno = aLineNumber;
|
||||
errorInit.mColno = aColumnNumber;
|
||||
RefPtr<Event> event;
|
||||
|
||||
RefPtr<ErrorEvent> errorEvent =
|
||||
ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"),
|
||||
errorInit);
|
||||
if (!errorEvent) {
|
||||
if (aIsErrorEvent) {
|
||||
RootedDictionary<ErrorEventInit> errorInit(aCx);
|
||||
errorInit.mBubbles = false;
|
||||
errorInit.mCancelable = true;
|
||||
errorInit.mMessage = aMessage;
|
||||
errorInit.mFilename = aFilename;
|
||||
errorInit.mLineno = aLineNumber;
|
||||
errorInit.mColno = aColumnNumber;
|
||||
|
||||
event = ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"),
|
||||
errorInit);
|
||||
} else {
|
||||
event = Event::Constructor(sharedWorker, NS_LITERAL_STRING("error"),
|
||||
EventInit());
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
ThrowAndReport(window, NS_ERROR_UNEXPECTED);
|
||||
continue;
|
||||
}
|
||||
|
||||
errorEvent->SetTrusted(true);
|
||||
event->SetTrusted(true);
|
||||
|
||||
bool defaultActionEnabled;
|
||||
nsresult rv = sharedWorker->DispatchEvent(errorEvent, &defaultActionEnabled);
|
||||
nsresult rv = sharedWorker->DispatchEvent(event, &defaultActionEnabled);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowAndReport(window, rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!aIsErrorEvent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (defaultActionEnabled) {
|
||||
// Add the owning window to our list so that we will fire an error event
|
||||
// at it later.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue