Bug 1712930 - Part 6: Get rid of NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING; r=smaug
☠☠ backed out by a8c952dcf428 ☠ ☠
authorEdgar Chen <echen@mozilla.com>
Mon, 31 May 2021 12:57:17 +0000
changeset 653973 311ccf17a01d149dd601c41d054b2e98b868d952
parent 653972 c42f2270b5f846f63113e56529fb8edaf43ab343
child 653974 4a03c8b2aa1ad58d23e8279f1955a0c6af8b5667
push id2623
push userffxbld-merge
push dateMon, 02 Aug 2021 14:47:51 +0000
treeherdermozilla-release@8500ce65f7c6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1712930
milestone90.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1712930 - Part 6: Get rid of NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING; r=smaug Differential Revision: https://phabricator.services.mozilla.com/D116080
devtools/server/actors/network-monitor/utils/network-utils.js
dom/base/domerr.msg
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
dom/xhr/XMLHttpRequestWorker.cpp
xpcom/base/ErrorList.py
--- a/devtools/server/actors/network-monitor/utils/network-utils.js
+++ b/devtools/server/actors/network-monitor/utils/network-utils.js
@@ -294,17 +294,16 @@ const ErrorCodes = {
   NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED: 0x805303f3,
   NS_ERROR_DOM_BAD_URI: 0x805303f4,
   NS_ERROR_DOM_RETVAL_UNDEFINED: 0x805303f5,
   NS_ERROR_UNCATCHABLE_EXCEPTION: 0x805303f7,
   NS_ERROR_DOM_MALFORMED_URI: 0x805303f8,
   NS_ERROR_DOM_INVALID_HEADER_NAME: 0x805303f9,
   NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT: 0x805303fa,
   NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED: 0x805303fb,
-  NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING: 0x805303fc,
   NS_ERROR_DOM_JS_DECODING_ERROR: 0x80530402,
   NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT: 0x80530403,
   NS_ERROR_DOM_IMAGE_INVALID_REQUEST: 0x80530404,
   NS_ERROR_DOM_IMAGE_BROKEN: 0x80530405,
   NS_ERROR_DOM_CORP_FAILED: 0x8053040c,
   NS_SUCCESS_DOM_NO_OPERATION: 0x530001,
   NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW: 0x530002,
   NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE: 0x530003,
--- a/dom/base/domerr.msg
+++ b/dom/base/domerr.msg
@@ -134,14 +134,13 @@ DOM4_MSG_DEF(NotAllowedError,   "The pla
 DOM4_MSG_DEF(NotSupportedError, "The media resource indicated by the src attribute or assigned media provider object was not suitable.", NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR)
 
 DOM4_MSG_DEF(SyntaxError, "The URI is malformed.", NS_ERROR_DOM_MALFORMED_URI)
 DOM4_MSG_DEF(SyntaxError, "Invalid header name.", NS_ERROR_DOM_INVALID_HEADER_NAME)
 
 /* XMLHttpRequest errors. */
 DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest has an invalid context.", NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT)
 DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest state must be OPENED.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED)
-DOM4_MSG_DEF(InvalidStateError, "XMLHttpRequest must not be sending.", NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING)
 
 /* Image decode errors. */
 DOM4_MSG_DEF(EncodingError, "Node bound to inactive document.", NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT)
 DOM4_MSG_DEF(EncodingError, "Invalid image request.", NS_ERROR_DOM_IMAGE_INVALID_REQUEST)
 DOM4_MSG_DEF(EncodingError, "Invalid encoded image data.", NS_ERROR_DOM_IMAGE_BROKEN)
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -2814,61 +2814,61 @@ void XMLHttpRequestMainThread::Unsuppres
 void XMLHttpRequestMainThread::Send(
     const Nullable<
         DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString>&
         aData,
     ErrorResult& aRv) {
   NOT_CALLABLE_IN_SYNC_SEND_RV
 
   if (aData.IsNull()) {
-    aRv = SendInternal(nullptr);
+    SendInternal(nullptr, false, aRv);
     return;
   }
 
   if (aData.Value().IsDocument()) {
     BodyExtractor<Document> body(&aData.Value().GetAsDocument());
-    aRv = SendInternal(&body, true);
+    SendInternal(&body, true, aRv);
     return;
   }
 
   if (aData.Value().IsBlob()) {
     BodyExtractor<const Blob> body(&aData.Value().GetAsBlob());
-    aRv = SendInternal(&body);
+    SendInternal(&body, false, aRv);
     return;
   }
 
   if (aData.Value().IsArrayBuffer()) {
     BodyExtractor<const ArrayBuffer> body(&aData.Value().GetAsArrayBuffer());
-    aRv = SendInternal(&body);
+    SendInternal(&body, false, aRv);
     return;
   }
 
   if (aData.Value().IsArrayBufferView()) {
     BodyExtractor<const ArrayBufferView> body(
         &aData.Value().GetAsArrayBufferView());
-    aRv = SendInternal(&body);
+    SendInternal(&body, false, aRv);
     return;
   }
 
   if (aData.Value().IsFormData()) {
     BodyExtractor<const FormData> body(&aData.Value().GetAsFormData());
-    aRv = SendInternal(&body);
+    SendInternal(&body, false, aRv);
     return;
   }
 
   if (aData.Value().IsURLSearchParams()) {
     BodyExtractor<const URLSearchParams> body(
         &aData.Value().GetAsURLSearchParams());
-    aRv = SendInternal(&body);
+    SendInternal(&body, false, aRv);
     return;
   }
 
   if (aData.Value().IsUSVString()) {
     BodyExtractor<const nsAString> body(&aData.Value().GetAsUSVString());
-    aRv = SendInternal(&body, true);
+    SendInternal(&body, true, aRv);
     return;
   }
 }
 
 nsresult XMLHttpRequestMainThread::MaybeSilentSendFailure(nsresult aRv) {
   // Per spec, silently fail on async request failures; throw for sync.
   if (mFlagSynchronous) {
     mState = XMLHttpRequest_Binding::DONE;
@@ -2880,49 +2880,57 @@ nsresult XMLHttpRequestMainThread::Maybe
   Unused << NS_WARN_IF(
       NS_FAILED(DispatchToMainThread(NewRunnableMethod<ProgressEventType>(
           "dom::XMLHttpRequestMainThread::CloseRequestWithError", this,
           &XMLHttpRequestMainThread::CloseRequestWithError,
           ProgressEventType::error))));
   return NS_OK;
 }
 
-nsresult XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
-                                                bool aBodyIsDocumentOrString) {
+void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
+                                            bool aBodyIsDocumentOrString,
+                                            ErrorResult& aRv) {
   MOZ_ASSERT(NS_IsMainThread());
 
-  NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
+  if (!mPrincipal) {
+    aRv.Throw(NS_ERROR_NOT_INITIALIZED);
+    return;
+  }
 
   // Step 1
   if (mState != XMLHttpRequest_Binding::OPENED) {
-    return NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED);
+    return;
   }
 
   // Step 2
   if (mFlagSend) {
-    return NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING;
-  }
-
-  nsresult rv = CheckCurrentGlobalCorrectness();
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT;
+    aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
+    return;
+  }
+
+  if (NS_FAILED(CheckCurrentGlobalCorrectness())) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT);
+    return;
   }
 
   // If open() failed to create the channel, then throw a network error
   // as per spec. We really should create the channel here in send(), but
   // we have internal code relying on the channel being created in open().
   if (!mChannel) {
     mFlagSend = true;  // so CloseRequestWithError sets us to DONE.
-    return MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
+    aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
+    return;
   }
 
   // non-GET requests aren't allowed for blob.
   if (IsBlobURI(mRequestURL) && !mRequestMethod.EqualsLiteral("GET")) {
     mFlagSend = true;  // so CloseRequestWithError sets us to DONE.
-    return MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
+    aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
+    return;
   }
 
   // XXX We should probably send a warning to the JS console
   //     if there are no event listeners set and we are doing
   //     an asynchronous call.
 
   mUploadTransferred = 0;
   mUploadTotal = 0;
@@ -2933,19 +2941,21 @@ nsresult XMLHttpRequestMainThread::SendI
   nsCOMPtr<nsIInputStream> uploadStream;
   nsAutoCString uploadContentType;
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
   if (aBody && httpChannel && !mRequestMethod.EqualsLiteral("GET") &&
       !mRequestMethod.EqualsLiteral("HEAD")) {
     nsAutoCString charset;
     nsAutoCString defaultContentType;
     uint64_t size_u64;
-    rv = aBody->GetAsStream(getter_AddRefs(uploadStream), &size_u64,
-                            defaultContentType, charset);
-    NS_ENSURE_SUCCESS(rv, rv);
+    aRv = aBody->GetAsStream(getter_AddRefs(uploadStream), &size_u64,
+                             defaultContentType, charset);
+    if (aRv.Failed()) {
+      return;
+    }
 
     // make sure it fits within js MAX_SAFE_INTEGER
     mUploadTotal =
         net::InScriptableRange(size_u64) ? static_cast<int64_t>(size_u64) : -1;
 
     if (uploadStream) {
       // If author set no Content-Type, use the default from GetAsStream().
       mAuthorRequestHeaders.Get("content-type", uploadContentType);
@@ -2988,27 +2998,29 @@ nsresult XMLHttpRequestMainThread::SendI
   }
 
   mIsMappedArrayBuffer = false;
   if (mResponseType == XMLHttpRequestResponseType::Arraybuffer &&
       StaticPrefs::dom_mapped_arraybuffer_enabled()) {
     nsCOMPtr<nsIURI> uri;
     nsAutoCString scheme;
 
-    rv = mChannel->GetURI(getter_AddRefs(uri));
-    if (NS_SUCCEEDED(rv)) {
+    aRv = mChannel->GetURI(getter_AddRefs(uri));
+    if (!aRv.Failed()) {
       uri->GetScheme(scheme);
       if (scheme.LowerCaseEqualsLiteral("jar")) {
         mIsMappedArrayBuffer = true;
       }
     }
   }
 
-  rv = InitiateFetch(uploadStream.forget(), mUploadTotal, uploadContentType);
-  NS_ENSURE_SUCCESS(rv, rv);
+  aRv = InitiateFetch(uploadStream.forget(), mUploadTotal, uploadContentType);
+  if (aRv.Failed()) {
+    return;
+  }
 
   // Start our timeout
   mRequestSentTime = PR_Now();
   StartTimeoutTimer();
 
   mWaitingForOnStopRequest = true;
 
   // Step 8
@@ -3030,40 +3042,42 @@ nsresult XMLHttpRequestMainThread::SendI
           topInner->Suspend();
           mResumeTimeoutRunnable = new nsResumeTimeoutsEvent(topInner);
         }
       }
     }
 
     SuspendEventDispatching();
     StopProgressEventTimer();
+    auto scopeExit = MakeScopeExit([&] {
+      UnsuppressEventHandlingAndResume();
+      ResumeEventDispatching();
+    });
 
     SyncTimeoutType syncTimeoutType = MaybeStartSyncTimeoutTimer();
     if (syncTimeoutType == eErrorOrExpired) {
       Abort();
-      rv = NS_ERROR_DOM_NETWORK_ERR;
+      aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
+      return;
     }
 
-    if (NS_SUCCEEDED(rv)) {
-      nsAutoSyncOperation sync(mSuspendedDoc,
-                               SyncOperationBehavior::eSuspendInput);
-      if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
-        rv = NS_ERROR_UNEXPECTED;
-      }
-
-      // Time expired... We should throw.
-      if (syncTimeoutType == eTimerStarted && !mSyncTimeoutTimer) {
-        rv = NS_ERROR_DOM_NETWORK_ERR;
-      }
-
+    nsAutoSyncOperation sync(mSuspendedDoc,
+                             SyncOperationBehavior::eSuspendInput);
+    if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
       CancelSyncTimeoutTimer();
+      aRv.Throw(NS_ERROR_UNEXPECTED);
+      return;
     }
 
-    UnsuppressEventHandlingAndResume();
-    ResumeEventDispatching();
+    // Time expired... We should throw.
+    if (syncTimeoutType == eTimerStarted && !mSyncTimeoutTimer) {
+      CancelSyncTimeoutTimer();
+      aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
+      return;
+    }
   } else {
     // Now that we've successfully opened the channel, we can change state. Note
     // that this needs to come after the AsyncOpen() and rv check, because this
     // can run script that would try to restart this request, and that could end
     // up doing our AsyncOpen on a null channel if the reentered AsyncOpen
     // fails.
     StopProgressEventTimer();
 
@@ -3075,37 +3089,35 @@ nsresult XMLHttpRequestMainThread::SendI
     DispatchProgressEvent(this, ProgressEventType::loadstart, 0, -1);
     if (mUpload && !mUploadComplete) {
       DispatchProgressEvent(mUpload, ProgressEventType::loadstart, 0,
                             mUploadTotal);
     }
   }
 
   if (!mChannel) {
-    return MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
-  }
-
-  return rv;
+    aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR);
+  }
 }
 
 // http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-setrequestheader
 void XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
                                                 const nsACString& aValue,
                                                 ErrorResult& aRv) {
   NOT_CALLABLE_IN_SYNC_SEND_RV
 
   // Step 1
   if (mState != XMLHttpRequest_Binding::OPENED) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED);
     return;
   }
 
   // Step 2
   if (mFlagSend) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING);
+    aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
     return;
   }
 
   // Step 3
   nsAutoCString value;
   NS_TrimHTTPWhitespace(aValue, value);
 
   // Step 4
@@ -3225,36 +3237,36 @@ void XMLHttpRequestMainThread::OverrideM
     mOverrideMimeType.AssignLiteral(APPLICATION_OCTET_STREAM);
   }
 }
 
 bool XMLHttpRequestMainThread::MozBackgroundRequest() const {
   return mFlagBackgroundRequest;
 }
 
-nsresult XMLHttpRequestMainThread::SetMozBackgroundRequest(
-    bool aMozBackgroundRequest) {
+void XMLHttpRequestMainThread::SetMozBackgroundRequestExternal(
+    bool aMozBackgroundRequest, ErrorResult& aRv) {
   if (!IsSystemXHR()) {
-    return NS_ERROR_DOM_SECURITY_ERR;
+    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
   }
 
   if (mState != XMLHttpRequest_Binding::UNSENT) {
     // Can't change this while we're in the middle of something.
-    return NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING;
+    aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
+    return;
   }
 
   mFlagBackgroundRequest = aMozBackgroundRequest;
-
-  return NS_OK;
 }
 
 void XMLHttpRequestMainThread::SetMozBackgroundRequest(
     bool aMozBackgroundRequest, ErrorResult& aRv) {
   // No errors for this webIDL method on main-thread.
-  SetMozBackgroundRequest(aMozBackgroundRequest);
+  SetMozBackgroundRequestExternal(aMozBackgroundRequest, IgnoreErrors());
 }
 
 void XMLHttpRequestMainThread::SetOriginStack(
     UniquePtr<SerializedStackHolder> aOriginStack) {
   mOriginStack = std::move(aOriginStack);
 }
 
 void XMLHttpRequestMainThread::SetSource(
@@ -3279,17 +3291,17 @@ void XMLHttpRequestMainThread::SetWithCr
 
   // Return error if we're already processing a request.  Note that we can't use
   // ReadyState() here, because it can't differentiate between "opened" and
   // "sent", so we use mState directly.
 
   if ((mState != XMLHttpRequest_Binding::UNSENT &&
        mState != XMLHttpRequest_Binding::OPENED) ||
       mFlagSend || mIsAnon) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING);
+    aRv.ThrowInvalidStateError("XMLHttpRequest must not be sending.");
     return;
   }
 
   mFlagACwithCredentials = aWithCredentials;
 }
 
 nsresult XMLHttpRequestMainThread::ChangeState(uint16_t aState,
                                                bool aBroadcast) {
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -293,18 +293,18 @@ class XMLHttpRequestMainThread final : p
                                   ErrorResult& aRv) override;
 
   virtual XMLHttpRequestUpload* GetUpload(ErrorResult& aRv) override;
 
  private:
   virtual ~XMLHttpRequestMainThread();
 
   nsresult MaybeSilentSendFailure(nsresult aRv);
-  nsresult SendInternal(const BodyExtractorBase* aBody,
-                        bool aBodyIsDocumentOrString = false);
+  void SendInternal(const BodyExtractorBase* aBody,
+                    bool aBodyIsDocumentOrString, ErrorResult& aRv);
 
   bool IsCrossSiteCORSRequest() const;
   bool IsDeniedCrossSiteCORSRequest();
 
   void UnsuppressEventHandlingAndResume();
 
   void MaybeLowerChannelPriority();
 
@@ -313,17 +313,17 @@ class XMLHttpRequestMainThread final : p
       const Nullable<
           DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString>&
           aData,
       ErrorResult& aRv) override;
 
   virtual void SendInputStream(nsIInputStream* aInputStream,
                                ErrorResult& aRv) override {
     BodyExtractor<nsIInputStream> body(aInputStream);
-    aRv = SendInternal(&body);
+    SendInternal(&body, false, aRv);
   }
 
   void RequestErrorSteps(const ProgressEventType aEventType,
                          const nsresult aOptionalException, ErrorResult& aRv);
 
   void Abort() {
     IgnoredErrorResult rv;
     AbortInternal(rv);
@@ -388,17 +388,18 @@ class XMLHttpRequestMainThread final : p
   nsresult GetResponseTextForJSON(nsAString& aString);
   void GetResponseText(XMLHttpRequestStringSnapshot& aSnapshot,
                        ErrorResult& aRv);
 
   virtual Document* GetResponseXML(ErrorResult& aRv) override;
 
   virtual bool MozBackgroundRequest() const override;
 
-  nsresult SetMozBackgroundRequest(bool aMozBackgroundRequest);
+  void SetMozBackgroundRequestExternal(bool aMozBackgroundRequest,
+                                       ErrorResult& aRv);
 
   virtual void SetMozBackgroundRequest(bool aMozBackgroundRequest,
                                        ErrorResult& aRv) override;
 
   void SetOriginStack(UniquePtr<SerializedStackHolder> aOriginStack);
 
   void SetSource(UniquePtr<ProfileChunkedBuffer> aSource);
 
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -527,16 +527,17 @@ class SetBackgroundRequestRunnable final
   SetBackgroundRequestRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                                bool aValue)
       : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue) {}
 
  private:
   ~SetBackgroundRequestRunnable() = default;
 
   virtual void RunOnMainThread(ErrorResult& aRv) override {
+    // XXXedgar, do we intend to ignore the errors?
     mProxy->mXHR->SetMozBackgroundRequest(mValue, aRv);
   }
 };
 
 class SetWithCredentialsRunnable final : public WorkerThreadProxySyncRunnable {
   bool mValue;
 
  public:
@@ -690,22 +691,22 @@ class OpenRunnable final : public Worker
 
  private:
   ~OpenRunnable() = default;
 
   virtual void RunOnMainThread(ErrorResult& aRv) override {
     WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
     mProxy->mWorkerPrivate = mWorkerPrivate;
 
-    aRv = MainThreadRunInternal();
+    MainThreadRunInternal(aRv);
 
     mProxy->mWorkerPrivate = oldWorker;
   }
 
-  nsresult MainThreadRunInternal();
+  void MainThreadRunInternal(ErrorResult& aRv);
 };
 
 class SetRequestHeaderRunnable final : public WorkerThreadProxySyncRunnable {
   nsCString mHeader;
   nsCString mValue;
 
  public:
   SetRequestHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
@@ -1201,77 +1202,73 @@ void AbortRunnable::RunOnMainThread(Erro
 
   mProxy->mXHR->Abort(aRv);
 
   mProxy->mWorkerPrivate = oldWorker;
 
   mProxy->Reset();
 }
 
-nsresult OpenRunnable::MainThreadRunInternal() {
+void OpenRunnable::MainThreadRunInternal(ErrorResult& aRv) {
   if (!mProxy->Init()) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
   }
 
   if (mBackgroundRequest) {
-    nsresult rv = mProxy->mXHR->SetMozBackgroundRequest(mBackgroundRequest);
-    NS_ENSURE_SUCCESS(rv, rv);
+    mProxy->mXHR->SetMozBackgroundRequestExternal(mBackgroundRequest, aRv);
+    if (aRv.Failed()) {
+      return;
+    }
   }
 
   if (mOriginStack) {
     mProxy->mXHR->SetOriginStack(std::move(mOriginStack));
   }
 
-  ErrorResult rv;
-
   if (mWithCredentials) {
-    mProxy->mXHR->SetWithCredentials(mWithCredentials, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      return rv.StealNSResult();
+    mProxy->mXHR->SetWithCredentials(mWithCredentials, aRv);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return;
     }
   }
 
   if (mTimeout) {
-    mProxy->mXHR->SetTimeout(mTimeout, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      return rv.StealNSResult();
+    mProxy->mXHR->SetTimeout(mTimeout, aRv);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return;
     }
   }
 
   if (!mMimeTypeOverride.IsVoid()) {
-    mProxy->mXHR->OverrideMimeType(mMimeTypeOverride, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      return rv.StealNSResult();
+    mProxy->mXHR->OverrideMimeType(mMimeTypeOverride, aRv);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return;
     }
   }
 
   MOZ_ASSERT(!mProxy->mInOpen);
   mProxy->mInOpen = true;
 
   mProxy->mXHR->Open(
       mMethod, mURL, true, mUser.WasPassed() ? mUser.Value() : VoidString(),
-      mPassword.WasPassed() ? mPassword.Value() : VoidString(), rv);
+      mPassword.WasPassed() ? mPassword.Value() : VoidString(), aRv);
 
   MOZ_ASSERT(mProxy->mInOpen);
   mProxy->mInOpen = false;
 
-  if (NS_WARN_IF(rv.Failed())) {
-    return rv.StealNSResult();
+  if (NS_WARN_IF(aRv.Failed())) {
+    return;
   }
 
   if (mSource) {
     mProxy->mXHR->SetSource(std::move(mSource));
   }
 
-  mProxy->mXHR->SetResponseType(mResponseType, rv);
-  if (NS_WARN_IF(rv.Failed())) {
-    return rv.StealNSResult();
-  }
-
-  return NS_OK;
+  mProxy->mXHR->SetResponseType(mResponseType, aRv);
 }
 
 void SendRunnable::RunOnMainThread(ErrorResult& aRv) {
   nsresult rv = mProxy->mXHR->CheckCurrentGlobalCorrectness();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv = rv;
     return;
   }
--- a/xpcom/base/ErrorList.py
+++ b/xpcom/base/ErrorList.py
@@ -710,17 +710,16 @@ with modules["DOM"]:
     # A way to represent uncatchable exceptions
     errors["NS_ERROR_UNCATCHABLE_EXCEPTION"] = FAILURE(1015)
 
     errors["NS_ERROR_DOM_MALFORMED_URI"] = FAILURE(1016)
     errors["NS_ERROR_DOM_INVALID_HEADER_NAME"] = FAILURE(1017)
 
     errors["NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT"] = FAILURE(1018)
     errors["NS_ERROR_DOM_INVALID_STATE_XHR_MUST_BE_OPENED"] = FAILURE(1019)
-    errors["NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_SENDING"] = FAILURE(1020)
 
     # When manipulating the bytecode cache with the JS API, some transcoding
     # errors, such as a different bytecode format can cause failures of the
     # decoding process.
     errors["NS_ERROR_DOM_JS_DECODING_ERROR"] = FAILURE(1026)
 
     # Image decode errors.
     errors["NS_ERROR_DOM_IMAGE_INACTIVE_DOCUMENT"] = FAILURE(1027)