diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 1022f628b1d1..ce854108fc3e 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -44,6 +44,7 @@ #include "mozilla/dom/VisualViewport.h" #include "mozilla/dom/WindowProxyHolder.h" #include "mozilla/IntegerPrintfMacros.h" +#include "mozilla/Result.h" #if defined(MOZ_WIDGET_ANDROID) # include "mozilla/dom/WindowOrientationObserver.h" #endif @@ -5439,10 +5440,11 @@ Maybe nsGlobalWindowInner::GetClientState() const { MOZ_ASSERT(NS_IsMainThread()); Maybe clientState; if (mClientSource) { - ClientState state; - nsresult rv = mClientSource->SnapshotState(&state); - if (NS_SUCCEEDED(rv)) { - clientState.emplace(state); + Result res = mClientSource->SnapshotState(); + if (res.isOk()) { + clientState.emplace(res.unwrap()); + } else { + res.unwrapErr().SuppressException(); } } return clientState; diff --git a/dom/bindings/ErrorResult.h b/dom/bindings/ErrorResult.h index ad3fbaa06322..15984517e7a3 100644 --- a/dom/bindings/ErrorResult.h +++ b/dom/bindings/ErrorResult.h @@ -724,6 +724,27 @@ class CopyableErrorResult CopyableErrorResult(CopyableErrorResult&& aRHS) : BaseErrorResult(std::move(aRHS)) {} + explicit CopyableErrorResult(ErrorResult&& aRHS) : BaseErrorResult() { + // We must not copy JS exceptions since it can too easily lead to + // off-thread use. Assert this and fall back to a generic error + // in release builds. + MOZ_DIAGNOSTIC_ASSERT( + !aRHS.IsJSException(), + "Attempt to copy from ErrorResult with a JS exception value."); + if (aRHS.IsJSException()) { + aRHS.SuppressException(); + Throw(NS_ERROR_FAILURE); + } else { + // We could avoid the cast here if we had a move constructor on + // TErrorResult templated on the cleanup policy type, but then we'd have + // to either inline the impl or force all possible instantiations or + // something. This is a bit simpler, and not that different from our copy + // constructor. + auto val = reinterpret_cast(aRHS); + operator=(val); + } + } + explicit CopyableErrorResult(nsresult aRv) : BaseErrorResult(aRv) {} // This operator is deprecated and ideally shouldn't be used. diff --git a/dom/clients/api/Client.cpp b/dom/clients/api/Client.cpp index 4a05c602795f..b5fd0e012df3 100644 --- a/dom/clients/api/Client.cpp +++ b/dom/clients/api/Client.cpp @@ -161,9 +161,11 @@ already_AddRefed Client::Focus(CallerType aCallerType, ClientInfoAndState(ipcClientInfo, aResult.ToIPC())); outerPromise->MaybeResolve(newClient); }, - [holder, outerPromise](nsresult aResult) { + [holder, outerPromise](const CopyableErrorResult& aResult) { holder->Complete(); - outerPromise->MaybeReject(aResult); + // MaybeReject needs a non-const result, so make a copy. + CopyableErrorResult result(aResult); + outerPromise->MaybeReject(result); }) ->Track(*holder); @@ -198,7 +200,7 @@ already_AddRefed Client::Navigate(const nsAString& aURL, new Client(self->mGlobal, aResult.get_ClientInfoAndState()); outerPromise->MaybeResolve(newClient); }, - [self, outerPromise](nsresult aResult) { + [self, outerPromise](const CopyableErrorResult& aResult) { // TODO: Improve this error in bug 1412856. Ideally we should throw // the TypeError in the child process and pass it back to here. outerPromise->MaybeReject(NS_ERROR_DOM_TYPE_ERR); diff --git a/dom/clients/api/ClientDOMUtil.h b/dom/clients/api/ClientDOMUtil.h index 5181b061b26a..d71ad6f65fe3 100644 --- a/dom/clients/api/ClientDOMUtil.h +++ b/dom/clients/api/ClientDOMUtil.h @@ -10,6 +10,7 @@ #include "mozilla/dom/ClientOpPromise.h" #include "mozilla/dom/DOMMozPromiseRequestHolder.h" #include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/ErrorResult.h" class nsIGlobalObject; @@ -37,7 +38,7 @@ void StartClientManagerOp(Func aFunc, const Arg& aArg, nsIGlobalObject* aGlobal, holder->Complete(); aResolve(aResult); }, - [aReject, holder](nsresult aResult) { + [aReject, holder](const CopyableErrorResult& aResult) { holder->Complete(); aReject(aResult); }) diff --git a/dom/clients/api/Clients.cpp b/dom/clients/api/Clients.cpp index e31dbe505ef6..06a3cdc20daf 100644 --- a/dom/clients/api/Clients.cpp +++ b/dom/clients/api/Clients.cpp @@ -103,7 +103,7 @@ already_AddRefed Clients::Get(const nsAString& aClientID, SystemGroup::Dispatch(TaskCategory::Other, r.forget()); outerPromise->MaybeResolveWithUndefined(); }, - [outerPromise, holder](nsresult aResult) { + [outerPromise, holder](const CopyableErrorResult& aResult) { holder->Complete(); outerPromise->MaybeResolveWithUndefined(); }) @@ -188,7 +188,11 @@ already_AddRefed Clients::MatchAll(const ClientQueryOptions& aOptions, clientList.Sort(MatchAllComparator()); outerPromise->MaybeResolve(clientList); }, - [outerPromise](nsresult aResult) { outerPromise->MaybeReject(aResult); }); + [outerPromise](const CopyableErrorResult& aResult) { + // MaybeReject needs a non-const result, so make a copy. + CopyableErrorResult result(aResult); + outerPromise->MaybeReject(result); + }); return outerPromise.forget(); } @@ -237,7 +241,7 @@ already_AddRefed Clients::OpenWindow(const nsAString& aURL, new Client(global, aResult.get_ClientInfoAndState()); outerPromise->MaybeResolve(client); }, - [outerPromise](nsresult aResult) { + [outerPromise](const CopyableErrorResult& aResult) { // TODO: Improve this error in bug 1412856. Ideally we should throw // the TypeError in the child process and pass it back to here. outerPromise->MaybeReject(NS_ERROR_DOM_TYPE_ERR); @@ -272,7 +276,11 @@ already_AddRefed Clients::Claim(ErrorResult& aRv) { [outerPromise](const ClientOpResult& aResult) { outerPromise->MaybeResolveWithUndefined(); }, - [outerPromise](nsresult aResult) { outerPromise->MaybeReject(aResult); }); + [outerPromise](const CopyableErrorResult& aResult) { + // MaybeReject needs a non-const result, so make a copy. + CopyableErrorResult result(aResult); + outerPromise->MaybeReject(result); + }); return outerPromise.forget(); } diff --git a/dom/clients/manager/ClientHandle.cpp b/dom/clients/manager/ClientHandle.cpp index da75d2a026ed..833f095c65c5 100644 --- a/dom/clients/manager/ClientHandle.cpp +++ b/dom/clients/manager/ClientHandle.cpp @@ -54,7 +54,9 @@ void ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs, }, [aRejectCallback] { MOZ_DIAGNOSTIC_ASSERT(aRejectCallback); - aRejectCallback(NS_ERROR_DOM_INVALID_STATE_ERR); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + aRejectCallback(rv); }); } @@ -100,10 +102,10 @@ void ClientHandle::ExecutionReady(const ClientInfo& aClientInfo) { const ClientInfo& ClientHandle::Info() const { return mClientInfo; } -RefPtr ClientHandle::Control( +RefPtr ClientHandle::Control( const ServiceWorkerDescriptor& aServiceWorker) { - RefPtr outerPromise = - new GenericPromise::Private(__func__); + RefPtr outerPromise = + new GenericErrorResultPromise::Private(__func__); // We should never have a cross-origin controller. Since this would be // same-origin policy violation we do a full release assertion here. @@ -116,7 +118,7 @@ RefPtr ClientHandle::Control( outerPromise->Resolve(true, __func__); }, [outerPromise](const ClientOpResult& aResult) { - outerPromise->Reject(aResult.get_nsresult(), __func__); + outerPromise->Reject(aResult.get_CopyableErrorResult(), __func__); }); return outerPromise.forget(); @@ -133,17 +135,18 @@ RefPtr ClientHandle::Focus(CallerType aCallerType) { ClientState::FromIPC(aResult.get_IPCClientState()), __func__); }, [outerPromise](const ClientOpResult& aResult) { - outerPromise->Reject(aResult.get_nsresult(), __func__); + outerPromise->Reject(aResult.get_CopyableErrorResult(), __func__); }); return outerPromise.forget(); } -RefPtr ClientHandle::PostMessage( +RefPtr ClientHandle::PostMessage( StructuredCloneData& aData, const ServiceWorkerDescriptor& aSource) { if (IsShutdown()) { - return GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return GenericErrorResultPromise::CreateAndReject(rv, __func__); } ClientPostMessageArgs args; @@ -151,12 +154,13 @@ RefPtr ClientHandle::PostMessage( if (!aData.BuildClonedMessageDataForBackgroundChild( GetActor()->Manager()->Manager(), args.clonedData())) { - return GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return GenericErrorResultPromise::CreateAndReject(rv, __func__); } - RefPtr outerPromise = - new GenericPromise::Private(__func__); + RefPtr outerPromise = + new GenericErrorResultPromise::Private(__func__); StartOp( std::move(args), @@ -164,7 +168,7 @@ RefPtr ClientHandle::PostMessage( outerPromise->Resolve(true, __func__); }, [outerPromise](const ClientOpResult& aResult) { - outerPromise->Reject(aResult.get_nsresult(), __func__); + outerPromise->Reject(aResult.get_CopyableErrorResult(), __func__); }); return outerPromise.forget(); diff --git a/dom/clients/manager/ClientHandle.h b/dom/clients/manager/ClientHandle.h index b64777a5b15d..5d373f710d96 100644 --- a/dom/clients/manager/ClientHandle.h +++ b/dom/clients/manager/ClientHandle.h @@ -71,7 +71,8 @@ class ClientHandle final : public ClientThing { // Mark the ClientSource attached to this handle as controlled by the // given service worker. The promise will resolve true if the ClientSource // is successfully marked or reject if the operation could not be completed. - RefPtr Control(const ServiceWorkerDescriptor& aServiceWorker); + RefPtr Control( + const ServiceWorkerDescriptor& aServiceWorker); // Focus the Client if possible. If successful the promise will resolve with // a new ClientState snapshot after focus has completed. If focusing fails @@ -84,8 +85,8 @@ class ClientHandle final : public ClientThing { // returned promise will resolve if the MessageEvent is dispatched or if // it triggers an error handled in the Client's context. Other errors // will result in the promise rejecting. - RefPtr PostMessage(ipc::StructuredCloneData& aData, - const ServiceWorkerDescriptor& aSource); + RefPtr PostMessage( + ipc::StructuredCloneData& aData, const ServiceWorkerDescriptor& aSource); // Return a Promise that resolves when the ClientHandle object is detached // from its remote actors. This will happen if the ClientSource is destroyed diff --git a/dom/clients/manager/ClientHandleOpChild.cpp b/dom/clients/manager/ClientHandleOpChild.cpp index 67fbb3b905a7..1366ff33f59b 100644 --- a/dom/clients/manager/ClientHandleOpChild.cpp +++ b/dom/clients/manager/ClientHandleOpChild.cpp @@ -13,15 +13,17 @@ namespace dom { void ClientHandleOpChild::ActorDestroy(ActorDestroyReason aReason) { mClientHandle = nullptr; - mRejectCallback(NS_ERROR_DOM_ABORT_ERR); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_ABORT_ERR); + mRejectCallback(rv); } mozilla::ipc::IPCResult ClientHandleOpChild::Recv__delete__( const ClientOpResult& aResult) { mClientHandle = nullptr; - if (aResult.type() == ClientOpResult::Tnsresult && - NS_FAILED(aResult.get_nsresult())) { - mRejectCallback(aResult.get_nsresult()); + if (aResult.type() == ClientOpResult::TCopyableErrorResult && + aResult.get_CopyableErrorResult().Failed()) { + mRejectCallback(aResult.get_CopyableErrorResult()); return IPC_OK(); } mResolveCallback(aResult); diff --git a/dom/clients/manager/ClientHandleOpParent.cpp b/dom/clients/manager/ClientHandleOpParent.cpp index b0b6a7fc60fb..61200e75945b 100644 --- a/dom/clients/manager/ClientHandleOpParent.cpp +++ b/dom/clients/manager/ClientHandleOpParent.cpp @@ -49,8 +49,9 @@ void ClientHandleOpParent::Init(ClientOpConstructorArgs&& aArgs) { orig.clonedData()); if (!data.BuildClonedMessageDataForBackgroundParent( source->Manager()->Manager(), rebuild.clonedData())) { - Unused << PClientHandleOpParent::Send__delete__( - this, NS_ERROR_DOM_ABORT_ERR); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_ABORT_ERR); + Unused << PClientHandleOpParent::Send__delete__(this, rv); return; } @@ -72,7 +73,7 @@ void ClientHandleOpParent::Init(ClientOpConstructorArgs&& aArgs) { Unused << PClientHandleOpParent::Send__delete__(this, aResult); }, - [this](nsresult aRv) { + [this](const CopyableErrorResult& aRv) { mPromiseRequestHolder.Complete(); Unused << PClientHandleOpParent::Send__delete__(this, aRv); }) @@ -80,8 +81,9 @@ void ClientHandleOpParent::Init(ClientOpConstructorArgs&& aArgs) { }, [=](nsresult failure) { mSourcePromiseRequestHolder.Complete(); - Unused << PClientHandleOpParent::Send__delete__( - this, NS_ERROR_DOM_ABORT_ERR); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_ABORT_ERR); + Unused << PClientHandleOpParent::Send__delete__(this, rv); return; }) ->Track(mSourcePromiseRequestHolder); diff --git a/dom/clients/manager/ClientIPCTypes.ipdlh b/dom/clients/manager/ClientIPCTypes.ipdlh index 55d4a3859e71..17fe458d17bb 100644 --- a/dom/clients/manager/ClientIPCTypes.ipdlh +++ b/dom/clients/manager/ClientIPCTypes.ipdlh @@ -13,6 +13,7 @@ using FrameType from "mozilla/dom/ClientIPCUtils.h"; using mozilla::StorageAccess from "mozilla/dom/ClientIPCUtils.h"; using VisibilityState from "mozilla/dom/ClientIPCUtils.h"; using CallerType from "mozilla/dom/BindingIPCUtils.h"; +using mozilla::CopyableErrorResult from "ipc/ErrorIPCUtils.h"; namespace mozilla { namespace dom { @@ -144,7 +145,7 @@ struct ClientNavigateOpConstructorArgs union ClientOpResult { - nsresult; + CopyableErrorResult; IPCClientState; ClientInfoAndState; ClientList; diff --git a/dom/clients/manager/ClientManagerOpChild.cpp b/dom/clients/manager/ClientManagerOpChild.cpp index 0869c9f3b737..290c31989311 100644 --- a/dom/clients/manager/ClientManagerOpChild.cpp +++ b/dom/clients/manager/ClientManagerOpChild.cpp @@ -23,9 +23,9 @@ void ClientManagerOpChild::ActorDestroy(ActorDestroyReason aReason) { mozilla::ipc::IPCResult ClientManagerOpChild::Recv__delete__( const ClientOpResult& aResult) { mClientManager = nullptr; - if (aResult.type() == ClientOpResult::Tnsresult && - NS_FAILED(aResult.get_nsresult())) { - mPromise->Reject(aResult.get_nsresult(), __func__); + if (aResult.type() == ClientOpResult::TCopyableErrorResult && + aResult.get_CopyableErrorResult().Failed()) { + mPromise->Reject(aResult.get_CopyableErrorResult(), __func__); mPromise = nullptr; return IPC_OK(); } diff --git a/dom/clients/manager/ClientManagerOpParent.cpp b/dom/clients/manager/ClientManagerOpParent.cpp index 7d893648d8f8..074b9bc9d013 100644 --- a/dom/clients/manager/ClientManagerOpParent.cpp +++ b/dom/clients/manager/ClientManagerOpParent.cpp @@ -30,7 +30,7 @@ void ClientManagerOpParent::DoServiceOp(Method aMethod, Args&&... aArgs) { mPromiseRequestHolder.Complete(); Unused << PClientManagerOpParent::Send__delete__(this, aResult); }, - [this](nsresult aRv) { + [this](const CopyableErrorResult& aRv) { mPromiseRequestHolder.Complete(); Unused << PClientManagerOpParent::Send__delete__(this, aRv); }) diff --git a/dom/clients/manager/ClientManagerService.cpp b/dom/clients/manager/ClientManagerService.cpp index 13471ffe6a88..394109c18ec7 100644 --- a/dom/clients/manager/ClientManagerService.cpp +++ b/dom/clients/manager/ClientManagerService.cpp @@ -280,7 +280,9 @@ RefPtr ClientManagerService::Navigate( ClientSourceParent* source = FindSource(aArgs.target().id(), aArgs.target().principalInfo()); if (!source) { - return ClientOpPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_FAILURE); + return ClientOpPromise::CreateAndReject(rv, __func__); } PClientManagerParent* manager = source->Manager(); @@ -362,7 +364,9 @@ class PromiseListHolder final { self->ProcessCompletion(); } }, - [self](nsresult aResult) { self->ProcessCompletion(); }); + [self](const CopyableErrorResult& aResult) { + self->ProcessCompletion(); + }); } void MaybeFinish() { @@ -442,11 +446,16 @@ RefPtr ClaimOnMainThread( RefPtr swm = ServiceWorkerManager::GetInstance(); NS_ENSURE_TRUE_VOID(swm); - RefPtr inner = swm->MaybeClaimClient(clientInfo, desc); + RefPtr inner = + swm->MaybeClaimClient(clientInfo, desc); inner->Then( SystemGroup::EventTargetFor(TaskCategory::Other), __func__, - [promise](bool aResult) { promise->Resolve(NS_OK, __func__); }, - [promise](nsresult aRv) { promise->Reject(aRv, __func__); }); + [promise](bool aResult) { + promise->Resolve(CopyableErrorResult(), __func__); + }, + [promise](const CopyableErrorResult& aRv) { + promise->Reject(aRv, __func__); + }); scopeExit.release(); }); @@ -516,7 +525,9 @@ RefPtr ClientManagerService::GetInfoAndState( ClientSourceParent* source = FindSource(aArgs.id(), aArgs.principalInfo()); if (!source) { - return ClientOpPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_FAILURE); + return ClientOpPromise::CreateAndReject(rv, __func__); } if (!source->ExecutionReady()) { @@ -530,7 +541,9 @@ RefPtr ClientManagerService::GetInfoAndState( self->FindSource(aArgs.id(), aArgs.principalInfo()); if (!source) { - return ClientOpPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_FAILURE); + return ClientOpPromise::CreateAndReject(rv, __func__); } return source->StartOp(aArgs); diff --git a/dom/clients/manager/ClientNavigateOpChild.cpp b/dom/clients/manager/ClientNavigateOpChild.cpp index 294afa3bb04b..f5b7cf2c3ee8 100644 --- a/dom/clients/manager/ClientNavigateOpChild.cpp +++ b/dom/clients/manager/ClientNavigateOpChild.cpp @@ -73,7 +73,7 @@ class NavigateLoadListener final : public nsIWebProgressListener, // console you also need to update the 'aFromPrivateWindow' argument. rv = ssm->CheckSameOriginURI(mBaseURL, channelURL, false, false); if (NS_FAILED(rv)) { - mPromise->Resolve(NS_OK, __func__); + mPromise->Resolve(CopyableErrorResult(), __func__); return NS_OK; } @@ -158,14 +158,16 @@ RefPtr ClientNavigateOpChild::DoNavigate( ClientSource* target = targetActor->GetSource(); if (!target) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(rv, __func__); } window = target->GetInnerWindow(); if (!window) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(rv, __func__); } } @@ -180,7 +182,11 @@ RefPtr ClientNavigateOpChild::DoNavigate( nsCOMPtr baseURL; nsresult rv = NS_NewURI(getter_AddRefs(baseURL), aArgs.baseURL()); if (NS_FAILED(rv)) { - return ClientOpPromise::CreateAndReject(rv, __func__); + // This is rather unexpected: This is the worker URL we passed from the + // parent, so we expect this to parse fine! + CopyableErrorResult result; + result.Throw(rv); + return ClientOpPromise::CreateAndReject(result, __func__); } // There is an edge case for view-source url here. According to the wpt test @@ -201,29 +207,32 @@ RefPtr ClientNavigateOpChild::DoNavigate( rv = NS_NewURI(getter_AddRefs(url), aArgs.url(), nullptr, shouldUseBaseURL ? baseURL.get() : nullptr); if (NS_FAILED(rv)) { - return ClientOpPromise::CreateAndReject(rv, __func__); + CopyableErrorResult result; + result.Throw(rv); + return ClientOpPromise::CreateAndReject(result, __func__); } if (url->GetSpecOrDefault().EqualsLiteral("about:blank")) { - return ClientOpPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); + CopyableErrorResult result; + result.Throw(NS_ERROR_FAILURE); + return ClientOpPromise::CreateAndReject(result, __func__); } RefPtr doc = window->GetExtantDoc(); if (!doc || !doc->IsActive()) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult result; + result.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(result, __func__); } nsCOMPtr principal = doc->NodePrincipal(); - if (!principal) { - return ClientOpPromise::CreateAndReject(rv, __func__); - } nsCOMPtr docShell = window->GetDocShell(); nsCOMPtr webProgress = do_GetInterface(docShell); if (!docShell || !webProgress) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult result; + result.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(result, __func__); } RefPtr loadState = new nsDocShellLoadState(url); @@ -240,7 +249,9 @@ RefPtr ClientNavigateOpChild::DoNavigate( loadState->SetFirstParty(true); rv = docShell->LoadURI(loadState, false); if (NS_FAILED(rv)) { - return ClientOpPromise::CreateAndReject(rv, __func__); + CopyableErrorResult result; + result.Throw(rv); + return ClientOpPromise::CreateAndReject(result, __func__); } RefPtr promise = @@ -286,7 +297,7 @@ void ClientNavigateOpChild::Init(const ClientNavigateOpConstructorArgs& aArgs) { mPromiseRequestHolder.Complete(); PClientNavigateOpChild::Send__delete__(this, aResult); }, - [this](nsresult aResult) { + [this](const CopyableErrorResult& aResult) { mPromiseRequestHolder.Complete(); PClientNavigateOpChild::Send__delete__(this, aResult); }) diff --git a/dom/clients/manager/ClientNavigateOpParent.cpp b/dom/clients/manager/ClientNavigateOpParent.cpp index c09ad69cb0f6..8cc3c89cd1d2 100644 --- a/dom/clients/manager/ClientNavigateOpParent.cpp +++ b/dom/clients/manager/ClientNavigateOpParent.cpp @@ -20,9 +20,9 @@ void ClientNavigateOpParent::ActorDestroy(ActorDestroyReason aReason) { IPCResult ClientNavigateOpParent::Recv__delete__( const ClientOpResult& aResult) { - if (aResult.type() == ClientOpResult::Tnsresult && - NS_FAILED(aResult.get_nsresult())) { - mPromise->Reject(aResult.get_nsresult(), __func__); + if (aResult.type() == ClientOpResult::TCopyableErrorResult && + aResult.get_CopyableErrorResult().Failed()) { + mPromise->Reject(aResult.get_CopyableErrorResult(), __func__); mPromise = nullptr; return IPC_OK(); } diff --git a/dom/clients/manager/ClientOpPromise.h b/dom/clients/manager/ClientOpPromise.h index d7c65e017a6d..150c6494daf7 100644 --- a/dom/clients/manager/ClientOpPromise.h +++ b/dom/clients/manager/ClientOpPromise.h @@ -6,6 +6,7 @@ #ifndef _mozilla_dom_ClientOpPromise_h #define _mozilla_dom_ClientOpPromise_h +#include "mozilla/ErrorResult.h" #include "mozilla/MozPromise.h" namespace mozilla { @@ -14,9 +15,12 @@ namespace dom { class ClientOpResult; class ClientState; -typedef MozPromise ClientOpPromise; +typedef MozPromise ClientOpPromise; -typedef MozPromise ClientStatePromise; +typedef MozPromise ClientStatePromise; + +typedef MozPromise + GenericErrorResultPromise; typedef std::function ClientOpCallback; diff --git a/dom/clients/manager/ClientOpenWindowOpChild.cpp b/dom/clients/manager/ClientOpenWindowOpChild.cpp index c19fce3e7e64..1e34fa7f1c49 100644 --- a/dom/clients/manager/ClientOpenWindowOpChild.cpp +++ b/dom/clients/manager/ClientOpenWindowOpChild.cpp @@ -28,7 +28,7 @@ void ClientOpenWindowOpChild::Init(const ClientOpenWindowArgs& aArgs) { mPromiseRequestHolder.Complete(); PClientOpenWindowOpChild::Send__delete__(this, aResult); }, - [this](nsresult aResult) { + [this](const CopyableErrorResult& aResult) { mPromiseRequestHolder.Complete(); PClientOpenWindowOpChild::Send__delete__(this, aResult); }) diff --git a/dom/clients/manager/ClientOpenWindowOpParent.cpp b/dom/clients/manager/ClientOpenWindowOpParent.cpp index 5e2bcb9b70c7..e9f51afa4171 100644 --- a/dom/clients/manager/ClientOpenWindowOpParent.cpp +++ b/dom/clients/manager/ClientOpenWindowOpParent.cpp @@ -20,9 +20,9 @@ void ClientOpenWindowOpParent::ActorDestroy(ActorDestroyReason aReason) { IPCResult ClientOpenWindowOpParent::Recv__delete__( const ClientOpResult& aResult) { - if (aResult.type() == ClientOpResult::Tnsresult && - NS_FAILED(aResult.get_nsresult())) { - mPromise->Reject(aResult.get_nsresult(), __func__); + if (aResult.type() == ClientOpResult::TCopyableErrorResult && + aResult.get_CopyableErrorResult().Failed()) { + mPromise->Reject(aResult.get_CopyableErrorResult(), __func__); mPromise = nullptr; return IPC_OK(); } diff --git a/dom/clients/manager/ClientOpenWindowUtils.cpp b/dom/clients/manager/ClientOpenWindowUtils.cpp index 58e374f2540e..d7b2631963c9 100644 --- a/dom/clients/manager/ClientOpenWindowUtils.cpp +++ b/dom/clients/manager/ClientOpenWindowUtils.cpp @@ -75,7 +75,7 @@ class WebProgressListener final : public nsIWebProgressListener, nsresult rv = securityManager->CheckSameOriginURI( doc->GetOriginalURI(), mBaseURI, false, isPrivateWin); if (NS_FAILED(rv)) { - mPromise->Resolve(NS_OK, __func__); + mPromise->Resolve(CopyableErrorResult(), __func__); mPromise = nullptr; return NS_OK; } @@ -295,7 +295,7 @@ void WaitForLoad(const ClientOpenWindowArgs& aArgs, ref->Then( aOuterWindow->EventTargetFor(TaskCategory::Other), __func__, [listener](const ClientOpResult& aResult) {}, - [listener](nsresult aResult) {}); + [listener](const CopyableErrorResult& aResult) {}); } #ifdef MOZ_WIDGET_ANDROID diff --git a/dom/clients/manager/ClientSource.cpp b/dom/clients/manager/ClientSource.cpp index 1697e9813722..a450cbbe5cc8 100644 --- a/dom/clients/manager/ClientSource.cpp +++ b/dom/clients/manager/ClientSource.cpp @@ -72,35 +72,32 @@ void ClientSource::ExecutionReady(const ClientSourceExecutionReadyArgs& aArgs) { }); } -nsresult ClientSource::SnapshotWindowState(ClientState* aStateOut) { +Result ClientSource::SnapshotWindowState() { MOZ_ASSERT(NS_IsMainThread()); nsPIDOMWindowInner* window = GetInnerWindow(); if (!window || !window->IsCurrentInnerWindow() || !window->HasActiveDocument()) { - *aStateOut = ClientState(ClientWindowState( - VisibilityState::Hidden, TimeStamp(), StorageAccess::eDeny, false)); - return NS_OK; + return ClientState(ClientWindowState(VisibilityState::Hidden, TimeStamp(), + StorageAccess::eDeny, false)); } Document* doc = window->GetExtantDoc(); + ErrorResult rv; if (NS_WARN_IF(!doc)) { - return NS_ERROR_UNEXPECTED; + rv.Throw(NS_ERROR_UNEXPECTED); + return Err(std::move(rv)); } - ErrorResult rv; bool focused = doc->HasFocus(rv); if (NS_WARN_IF(rv.Failed())) { - rv.SuppressException(); - return rv.StealNSResult(); + return Err(std::move(rv)); } StorageAccess storage = StorageAllowedForDocument(doc); - *aStateOut = ClientState(ClientWindowState( - doc->VisibilityState(), doc->LastFocusTime(), storage, focused)); - - return NS_OK; + return ClientState(ClientWindowState(doc->VisibilityState(), + doc->LastFocusTime(), storage, focused)); } WorkerPrivate* ClientSource::GetWorkerPrivate() const { @@ -448,13 +445,14 @@ RefPtr ClientSource::Control( } if (NS_WARN_IF(!controlAllowed)) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(rv, __func__); } SetController(ServiceWorkerDescriptor(aArgs.serviceWorker())); - return ClientOpPromise::CreateAndResolve(NS_OK, __func__); + return ClientOpPromise::CreateAndResolve(CopyableErrorResult(), __func__); } void ClientSource::InheritController( @@ -534,8 +532,9 @@ RefPtr ClientSource::Focus(const ClientFocusArgs& aArgs) { NS_ASSERT_OWNINGTHREAD(ClientSource); if (mClientInfo.Type() != ClientType::Window) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return ClientOpPromise::CreateAndReject(rv, __func__); } nsPIDOMWindowOuter* outer = nullptr; @@ -550,20 +549,21 @@ RefPtr ClientSource::Focus(const ClientFocusArgs& aArgs) { } if (!outer) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(rv, __func__); } MOZ_ASSERT(NS_IsMainThread()); nsFocusManager::FocusWindow(outer, aArgs.callerType()); - ClientState state; - nsresult rv = SnapshotState(&state); - if (NS_FAILED(rv)) { - return ClientOpPromise::CreateAndReject(rv, __func__); + Result state = SnapshotState(); + if (state.isErr()) { + return ClientOpPromise::CreateAndReject( + CopyableErrorResult(state.unwrapErr()), __func__); } - return ClientOpPromise::CreateAndResolve(state.ToIPC(), __func__); + return ClientOpPromise::CreateAndResolve(state.inspect().ToIPC(), __func__); } RefPtr ClientSource::PostMessage( @@ -577,10 +577,12 @@ RefPtr ClientSource::PostMessage( const RefPtr container = window->Navigator()->ServiceWorker(); container->ReceiveMessage(aArgs); - return ClientOpPromise::CreateAndResolve(NS_OK, __func__); + return ClientOpPromise::CreateAndResolve(CopyableErrorResult(), __func__); } - return ClientOpPromise::CreateAndReject(NS_ERROR_NOT_IMPLEMENTED, __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return ClientOpPromise::CreateAndReject(rv, __func__); } RefPtr ClientSource::Claim(const ClientClaimArgs& aArgs) { @@ -591,8 +593,9 @@ RefPtr ClientSource::Claim(const ClientClaimArgs& aArgs) { nsIGlobalObject* global = GetGlobal(); if (NS_WARN_IF(!global)) { - return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return ClientOpPromise::CreateAndReject(rv, __func__); } // Note, we cannot just mark the ClientSource controlled. We must go through @@ -601,8 +604,8 @@ RefPtr ClientSource::Claim(const ClientClaimArgs& aArgs) { // mode. In parent-process service worker mode the SWM is notified in the // parent-process in ClientManagerService::Claim(). - RefPtr innerPromise = - new GenericPromise::Private(__func__); + RefPtr innerPromise = + new GenericErrorResultPromise::Private(__func__); ServiceWorkerDescriptor swd(aArgs.serviceWorker()); nsCOMPtr r = NS_NewRunnableFunction( @@ -614,7 +617,8 @@ RefPtr ClientSource::Claim(const ClientClaimArgs& aArgs) { return; } - RefPtr p = swm->MaybeClaimClient(clientInfo, swd); + RefPtr p = + swm->MaybeClaimClient(clientInfo, swd); p->ChainTo(innerPromise.forget(), __func__); }); @@ -627,16 +631,17 @@ RefPtr ClientSource::Claim(const ClientClaimArgs& aArgs) { RefPtr outerPromise = new ClientOpPromise::Private(__func__); - auto holder = MakeRefPtr>(global); + auto holder = + MakeRefPtr>(global); innerPromise ->Then( mEventTarget, __func__, [outerPromise, holder](bool aResult) { holder->Complete(); - outerPromise->Resolve(NS_OK, __func__); + outerPromise->Resolve(CopyableErrorResult(), __func__); }, - [outerPromise, holder](nsresult aResult) { + [outerPromise, holder](const CopyableErrorResult& aResult) { holder->Complete(); outerPromise->Reject(aResult, __func__); }) @@ -647,36 +652,33 @@ RefPtr ClientSource::Claim(const ClientClaimArgs& aArgs) { RefPtr ClientSource::GetInfoAndState( const ClientGetInfoAndStateArgs& aArgs) { - ClientState state; - nsresult rv = SnapshotState(&state); - if (NS_FAILED(rv)) { - return ClientOpPromise::CreateAndReject(rv, __func__); + Result state = SnapshotState(); + if (state.isErr()) { + return ClientOpPromise::CreateAndReject( + CopyableErrorResult(state.unwrapErr()), __func__); } return ClientOpPromise::CreateAndResolve( - ClientInfoAndState(mClientInfo.ToIPC(), state.ToIPC()), __func__); + ClientInfoAndState(mClientInfo.ToIPC(), state.inspect().ToIPC()), + __func__); } -nsresult ClientSource::SnapshotState(ClientState* aStateOut) { +Result ClientSource::SnapshotState() { NS_ASSERT_OWNINGTHREAD(ClientSource); - MOZ_DIAGNOSTIC_ASSERT(aStateOut); if (mClientInfo.Type() == ClientType::Window) { MaybeCreateInitialDocument(); - nsresult rv = SnapshotWindowState(aStateOut); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; + return SnapshotWindowState(); } WorkerPrivate* workerPrivate = GetWorkerPrivate(); if (!workerPrivate) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + ErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return Err(std::move(rv)); } - *aStateOut = ClientState(ClientWorkerState(workerPrivate->StorageAccess())); - return NS_OK; + return ClientState(ClientWorkerState(workerPrivate->StorageAccess())); } nsISerialEventTarget* ClientSource::EventTarget() const { return mEventTarget; } diff --git a/dom/clients/manager/ClientSource.h b/dom/clients/manager/ClientSource.h index 07bb6d5752a1..c5c56dcc2f53 100644 --- a/dom/clients/manager/ClientSource.h +++ b/dom/clients/manager/ClientSource.h @@ -10,6 +10,7 @@ #include "mozilla/dom/ClientOpPromise.h" #include "mozilla/dom/ClientThing.h" #include "mozilla/dom/ServiceWorkerDescriptor.h" +#include "mozilla/Result.h" #include "mozilla/Variant.h" #ifdef XP_WIN @@ -78,7 +79,7 @@ class ClientSource final : public ClientThing { void MaybeCreateInitialDocument(); - nsresult SnapshotWindowState(ClientState* aStateOut); + Result SnapshotWindowState(); // Private methods called by ClientManager ClientSource(ClientManager* aManager, nsISerialEventTarget* aEventTarget, @@ -145,7 +146,7 @@ class ClientSource final : public ClientThing { RefPtr GetInfoAndState( const ClientGetInfoAndStateArgs& aArgs); - nsresult SnapshotState(ClientState* aStateOut); + Result SnapshotState(); nsISerialEventTarget* EventTarget() const; diff --git a/dom/clients/manager/ClientSourceOpChild.cpp b/dom/clients/manager/ClientSourceOpChild.cpp index 7547ec6a84a9..0ba191221e1d 100644 --- a/dom/clients/manager/ClientSourceOpChild.cpp +++ b/dom/clients/manager/ClientSourceOpChild.cpp @@ -30,8 +30,9 @@ void ClientSourceOpChild::DoSourceOp(Method aMethod, const Args& aArgs) { { ClientSource* source = GetSource(); if (!source) { - Unused << PClientSourceOpChild::Send__delete__(this, - NS_ERROR_DOM_ABORT_ERR); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_ABORT_ERR); + Unused << PClientSourceOpChild::Send__delete__(this, rv); return; } @@ -62,7 +63,7 @@ void ClientSourceOpChild::DoSourceOp(Method aMethod, const Args& aArgs) { mPromiseRequestHolder.Complete(); Unused << PClientSourceOpChild::Send__delete__(this, aResult); }, - [this, promise](nsresult aRv) { + [this, promise](const CopyableErrorResult& aRv) { mPromiseRequestHolder.Complete(); Unused << PClientSourceOpChild::Send__delete__(this, aRv); }) diff --git a/dom/clients/manager/ClientSourceOpParent.cpp b/dom/clients/manager/ClientSourceOpParent.cpp index 6287aef4f612..ad3415630630 100644 --- a/dom/clients/manager/ClientSourceOpParent.cpp +++ b/dom/clients/manager/ClientSourceOpParent.cpp @@ -21,8 +21,8 @@ void ClientSourceOpParent::ActorDestroy(ActorDestroyReason aReason) { } IPCResult ClientSourceOpParent::Recv__delete__(const ClientOpResult& aResult) { - if (aResult.type() == ClientOpResult::Tnsresult && - NS_FAILED(aResult.get_nsresult())) { + if (aResult.type() == ClientOpResult::TCopyableErrorResult && + aResult.get_CopyableErrorResult().Failed()) { // If a control message fails then clear the controller from // the ClientSourceParent. We eagerly marked it controlled at // the start of the operation. @@ -33,7 +33,7 @@ IPCResult ClientSourceOpParent::Recv__delete__(const ClientOpResult& aResult) { } } - mPromise->Reject(aResult.get_nsresult(), __func__); + mPromise->Reject(aResult.get_CopyableErrorResult(), __func__); mPromise = nullptr; return IPC_OK(); } diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp index a8370bda4c8b..d40a53b8cb60 100644 --- a/dom/serviceworkers/ServiceWorkerManager.cpp +++ b/dom/serviceworkers/ServiceWorkerManager.cpp @@ -377,13 +377,13 @@ void ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar) { mActor = static_cast(actor); } -RefPtr ServiceWorkerManager::StartControllingClient( +RefPtr ServiceWorkerManager::StartControllingClient( const ClientInfo& aClientInfo, ServiceWorkerRegistrationInfo* aRegistrationInfo, bool aControlClientHandle) { MOZ_DIAGNOSTIC_ASSERT(aRegistrationInfo->GetActive()); - RefPtr promise; + RefPtr promise; RefPtr self(this); const ServiceWorkerDescriptor& active = @@ -397,7 +397,7 @@ RefPtr ServiceWorkerManager::StartControllingClient( if (aControlClientHandle) { promise = entry.Data()->mClientHandle->Control(active); } else { - promise = GenericPromise::CreateAndResolve(false, __func__); + promise = GenericErrorResultPromise::CreateAndResolve(false, __func__); } entry.Data()->mRegistrationInfo = aRegistrationInfo; @@ -415,12 +415,12 @@ RefPtr ServiceWorkerManager::StartControllingClient( SystemGroup::EventTargetFor(TaskCategory::Other), __func__, [](bool) { // do nothing on success - return GenericPromise::CreateAndResolve(true, __func__); + return GenericErrorResultPromise::CreateAndResolve(true, __func__); }, - [self, aClientInfo](nsresult aRv) { + [self, aClientInfo](const CopyableErrorResult& aRv) { // failed to control, forget about this client self->StopControllingClient(aClientInfo); - return GenericPromise::CreateAndReject(aRv, __func__); + return GenericErrorResultPromise::CreateAndReject(aRv, __func__); }); } @@ -430,7 +430,7 @@ RefPtr ServiceWorkerManager::StartControllingClient( if (aControlClientHandle) { promise = clientHandle->Control(active); } else { - promise = GenericPromise::CreateAndResolve(false, __func__); + promise = GenericErrorResultPromise::CreateAndResolve(false, __func__); } aRegistrationInfo->StartControllingClient(); @@ -451,12 +451,12 @@ RefPtr ServiceWorkerManager::StartControllingClient( SystemGroup::EventTargetFor(TaskCategory::Other), __func__, [](bool) { // do nothing on success - return GenericPromise::CreateAndResolve(true, __func__); + return GenericErrorResultPromise::CreateAndResolve(true, __func__); }, - [self, aClientInfo](nsresult aRv) { + [self, aClientInfo](const CopyableErrorResult& aRv) { // failed to control, forget about this client self->StopControllingClient(aClientInfo); - return GenericPromise::CreateAndReject(aRv, __func__); + return GenericErrorResultPromise::CreateAndReject(aRv, __func__); }); } @@ -2241,7 +2241,7 @@ void ServiceWorkerManager::UpdateControlledClient( RefPtr self = this; - RefPtr p = + RefPtr p = StartControllingClient(aNewClientInfo, registration); p->Then( SystemGroup::EventTargetFor(TaskCategory::Other), __func__, @@ -2251,7 +2251,7 @@ void ServiceWorkerManager::UpdateControlledClient( }, // Controlling the new ClientInfo fail, do nothing. // Probably need to call LoadInfo::ClearController - [](nsresult aRv) {}); + [](const CopyableErrorResult& aRv) {}); } void ServiceWorkerManager::SoftUpdate(const OriginAttributes& aOriginAttributes, @@ -2467,20 +2467,23 @@ void ServiceWorkerManager::UpdateInternal( queue->ScheduleJob(job); } -RefPtr ServiceWorkerManager::MaybeClaimClient( +RefPtr ServiceWorkerManager::MaybeClaimClient( const ClientInfo& aClientInfo, ServiceWorkerRegistrationInfo* aWorkerRegistration) { MOZ_DIAGNOSTIC_ASSERT(aWorkerRegistration); if (!aWorkerRegistration->GetActive()) { - return GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, - __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return GenericErrorResultPromise::CreateAndReject(rv, __func__); } // Same origin check nsCOMPtr principal(aClientInfo.GetPrincipal()); if (!aWorkerRegistration->Principal()->Equals(principal)) { - return GenericPromise::CreateAndReject(NS_ERROR_DOM_SECURITY_ERR, __func__); + CopyableErrorResult rv; + rv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return GenericErrorResultPromise::CreateAndReject(rv, __func__); } // The registration that should be controlling the client @@ -2493,18 +2496,18 @@ RefPtr ServiceWorkerManager::MaybeClaimClient( if (aWorkerRegistration != matchingRegistration || aWorkerRegistration == controllingRegistration) { - return GenericPromise::CreateAndResolve(true, __func__); + return GenericErrorResultPromise::CreateAndResolve(true, __func__); } return StartControllingClient(aClientInfo, aWorkerRegistration); } -RefPtr ServiceWorkerManager::MaybeClaimClient( +RefPtr ServiceWorkerManager::MaybeClaimClient( const ClientInfo& aClientInfo, const ServiceWorkerDescriptor& aServiceWorker) { nsCOMPtr principal = aServiceWorker.GetPrincipal(); if (!principal) { - return GenericPromise::CreateAndResolve(false, __func__); + return GenericErrorResultPromise::CreateAndResolve(false, __func__); } RefPtr registration = @@ -2516,7 +2519,7 @@ RefPtr ServiceWorkerManager::MaybeClaimClient( // are done. The fix for this is to move the SWM to the parent process // so there are no consistency errors. if (NS_WARN_IF(!registration) || NS_WARN_IF(!registration->GetActive())) { - return GenericPromise::CreateAndResolve(false, __func__); + return GenericErrorResultPromise::CreateAndResolve(false, __func__); } return MaybeClaimClient(aClientInfo, registration); @@ -2564,7 +2567,8 @@ void ServiceWorkerManager::UpdateClientControllers( // Fire event after iterating mControlledClients is done to prevent // modification by reentering from the event handlers during iteration. for (auto& handle : handleList) { - RefPtr p = handle->Control(activeWorker->Descriptor()); + RefPtr p = + handle->Control(activeWorker->Descriptor()); RefPtr self = this; @@ -2575,7 +2579,7 @@ void ServiceWorkerManager::UpdateClientControllers( [](bool) { // do nothing on success }, - [self, clientInfo = handle->Info()](nsresult aRv) { + [self, clientInfo = handle->Info()](const CopyableErrorResult& aRv) { // failed to control, forget about this client self->StopControllingClient(clientInfo); }); diff --git a/dom/serviceworkers/ServiceWorkerManager.h b/dom/serviceworkers/ServiceWorkerManager.h index 9f9b4481922e..c538a35e519e 100644 --- a/dom/serviceworkers/ServiceWorkerManager.h +++ b/dom/serviceworkers/ServiceWorkerManager.h @@ -238,11 +238,11 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager, const nsString& aLine, uint32_t aLineNumber, uint32_t aColumnNumber, uint32_t aFlags, JSExnType aExnType); - MOZ_MUST_USE RefPtr MaybeClaimClient( + MOZ_MUST_USE RefPtr MaybeClaimClient( const ClientInfo& aClientInfo, ServiceWorkerRegistrationInfo* aWorkerRegistration); - MOZ_MUST_USE RefPtr MaybeClaimClient( + MOZ_MUST_USE RefPtr MaybeClaimClient( const ClientInfo& aClientInfo, const ServiceWorkerDescriptor& aServiceWorker); @@ -308,7 +308,7 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager, void Init(ServiceWorkerRegistrar* aRegistrar); - RefPtr StartControllingClient( + RefPtr StartControllingClient( const ClientInfo& aClientInfo, ServiceWorkerRegistrationInfo* aRegistrationInfo, bool aControlClientHandle = true); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 3bfaeefa608c..454afebb91c6 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -14,6 +14,7 @@ #include "js/MemoryMetrics.h" #include "js/SourceText.h" #include "MessageEventRunnable.h" +#include "mozilla/Result.h" #include "mozilla/ScopeExit.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/dom/BlobURLProtocolHandler.h" @@ -3079,9 +3080,15 @@ Maybe WorkerPrivate::GetClientInfo() const { const ClientState WorkerPrivate::GetClientState() const { MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data); MOZ_DIAGNOSTIC_ASSERT(data->mClientSource); - ClientState state; - data->mClientSource->SnapshotState(&state); - return state; + Result res = data->mClientSource->SnapshotState(); + if (res.isOk()) { + return res.unwrap(); + } + + // XXXbz Why is it OK to just ignore errors and return a default-initialized + // state here? + res.unwrapErr().SuppressException(); + return ClientState(); } const Maybe WorkerPrivate::GetController() {