Bug 1320297 - Thread-safe use of ErrorResult in WebSocket, r=qdot
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 28 Nov 2016 19:12:57 +0100
changeset 324457 2975832e0360aad762c41d7854bf3e7b5469400e
parent 324456 7e51bad5f8bdf26b6e0d09f55e49206ad9e11377
child 324458 11552f8437ae52c2b7f436bc39c8bc7dec08a2a0
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersqdot
bugs1320297
milestone53.0a1
Bug 1320297 - Thread-safe use of ErrorResult in WebSocket, r=qdot
dom/base/WebSocket.cpp
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -114,31 +114,29 @@ public:
 
   void AssertIsOnTargetThread() const
   {
     MOZ_ASSERT(IsTargetThread());
   }
 
   bool IsTargetThread() const;
 
-  void Init(JSContext* aCx,
-            nsIPrincipal* aPrincipal,
-            bool aIsServerSide,
-            const nsAString& aURL,
-            nsTArray<nsString>& aProtocolArray,
-            const nsACString& aScriptFile,
-            uint32_t aScriptLine,
-            uint32_t aScriptColumn,
-            ErrorResult& aRv,
-            bool* aConnectionFailed);
-
-  void AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
-                 nsITransportProvider* aTransportProvider,
-                 const nsACString& aNegotiatedExtensions,
-                 ErrorResult& aRv);
+  nsresult Init(JSContext* aCx,
+                nsIPrincipal* aPrincipal,
+                bool aIsServerSide,
+                const nsAString& aURL,
+                nsTArray<nsString>& aProtocolArray,
+                const nsACString& aScriptFile,
+                uint32_t aScriptLine,
+                uint32_t aScriptColumn,
+                bool* aConnectionFailed);
+
+  nsresult AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
+                     nsITransportProvider* aTransportProvider,
+                     const nsACString& aNegotiatedExtensions);
 
   nsresult ParseURL(const nsAString& aURL);
   nsresult InitializeConnection(nsIPrincipal* aPrincipal);
 
   // These methods when called can release the WebSocket object
   void FailConnection(uint16_t reasonCode,
                       const nsACString& aReasonString = EmptyCString());
   nsresult CloseConnection(uint16_t reasonCode,
@@ -1059,148 +1057,161 @@ protected:
 
 class InitRunnable final : public WebSocketMainThreadRunnable
 {
 public:
   InitRunnable(WebSocketImpl* aImpl, bool aIsServerSide,
                const nsAString& aURL,
                nsTArray<nsString>& aProtocolArray,
                const nsACString& aScriptFile, uint32_t aScriptLine,
-               uint32_t aScriptColumn,
-               ErrorResult& aRv, bool* aConnectionFailed)
+               uint32_t aScriptColumn, bool* aConnectionFailed)
     : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate,
                                   NS_LITERAL_CSTRING("WebSocket :: init"))
     , mImpl(aImpl)
     , mIsServerSide(aIsServerSide)
     , mURL(aURL)
     , mProtocolArray(aProtocolArray)
     , mScriptFile(aScriptFile)
     , mScriptLine(aScriptLine)
     , mScriptColumn(aScriptColumn)
-    , mRv(aRv)
     , mConnectionFailed(aConnectionFailed)
+    , mErrorCode(NS_OK)
   {
     MOZ_ASSERT(mWorkerPrivate);
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
+  nsresult
+  ErrorCode() const
+  {
+    return mErrorCode;
+  }
+
 protected:
   virtual bool InitWithWindow(nsPIDOMWindowInner* aWindow) override
   {
     AutoJSAPI jsapi;
     if (NS_WARN_IF(!jsapi.Init(aWindow))) {
-      mRv.Throw(NS_ERROR_FAILURE);
+      mErrorCode = NS_ERROR_FAILURE;
       return true;
     }
 
     ClearException ce(jsapi.cx());
 
     nsIDocument* doc = aWindow->GetExtantDoc();
     if (!doc) {
-      mRv.Throw(NS_ERROR_FAILURE);
+      mErrorCode = NS_ERROR_FAILURE;
       return true;
     }
 
     nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
     if (!principal) {
-      mRv.Throw(NS_ERROR_FAILURE);
+      mErrorCode = NS_ERROR_FAILURE;
       return true;
     }
 
-    mImpl->Init(jsapi.cx(), principal, mIsServerSide, mURL, mProtocolArray,
-                mScriptFile, mScriptLine, mScriptColumn, mRv,
-                mConnectionFailed);
+    mErrorCode =
+      mImpl->Init(jsapi.cx(), principal, mIsServerSide, mURL, mProtocolArray,
+                  mScriptFile, mScriptLine, mScriptColumn, mConnectionFailed);
     return true;
   }
 
   virtual bool InitWindowless(WorkerPrivate* aTopLevelWorkerPrivate) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aTopLevelWorkerPrivate && !aTopLevelWorkerPrivate->GetWindow());
 
-    mImpl->Init(nullptr, aTopLevelWorkerPrivate->GetPrincipal(), mIsServerSide,
-                mURL, mProtocolArray, mScriptFile, mScriptLine, mScriptColumn,
-                mRv, mConnectionFailed);
+    mErrorCode =
+      mImpl->Init(nullptr, aTopLevelWorkerPrivate->GetPrincipal(),
+                  mIsServerSide, mURL, mProtocolArray, mScriptFile, mScriptLine,
+                  mScriptColumn, mConnectionFailed);
     return true;
   }
 
   // Raw pointer. This worker runs synchronously.
   WebSocketImpl* mImpl;
 
   bool mIsServerSide;
   const nsAString& mURL;
   nsTArray<nsString>& mProtocolArray;
   nsCString mScriptFile;
   uint32_t mScriptLine;
   uint32_t mScriptColumn;
-  ErrorResult& mRv;
   bool* mConnectionFailed;
+  nsresult mErrorCode;
 };
 
 class AsyncOpenRunnable final : public WebSocketMainThreadRunnable
 {
 public:
-  AsyncOpenRunnable(WebSocketImpl* aImpl, ErrorResult& aRv)
+  explicit AsyncOpenRunnable(WebSocketImpl* aImpl)
     : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate,
                                   NS_LITERAL_CSTRING("WebSocket :: AsyncOpen"))
     , mImpl(aImpl)
-    , mRv(aRv)
+    , mErrorCode(NS_OK)
   {
     MOZ_ASSERT(mWorkerPrivate);
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
+  nsresult
+  ErrorCode() const
+  {
+    return mErrorCode;
+  }
+
 protected:
   virtual bool InitWithWindow(nsPIDOMWindowInner* aWindow) override
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(aWindow);
 
     nsIDocument* doc = aWindow->GetExtantDoc();
     if (!doc) {
-      mRv.Throw(NS_ERROR_FAILURE);
+      mErrorCode = NS_ERROR_FAILURE;
       return true;
     }
 
     nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
     if (!principal) {
-      mRv.Throw(NS_ERROR_FAILURE);
+      mErrorCode = NS_ERROR_FAILURE;
       return true;
     }
 
     uint64_t windowID = 0;
     nsCOMPtr<nsPIDOMWindowOuter> topWindow = aWindow->GetScriptableTop();
     nsCOMPtr<nsPIDOMWindowInner> topInner;
     if (topWindow) {
       topInner = topWindow->GetCurrentInnerWindow();
     }
 
     if (topInner) {
       windowID = topInner->WindowID();
     }
 
-    mImpl->AsyncOpen(principal, windowID, nullptr, EmptyCString(), mRv);
+    mErrorCode = mImpl->AsyncOpen(principal, windowID, nullptr, EmptyCString());
     return true;
   }
 
   virtual bool InitWindowless(WorkerPrivate* aTopLevelWorkerPrivate) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aTopLevelWorkerPrivate && !aTopLevelWorkerPrivate->GetWindow());
 
-    mImpl->AsyncOpen(aTopLevelWorkerPrivate->GetPrincipal(), 0, nullptr,
-                     EmptyCString(), mRv);
+    mErrorCode =
+      mImpl->AsyncOpen(aTopLevelWorkerPrivate->GetPrincipal(), 0, nullptr,
+                       EmptyCString());
     return true;
   }
 
 private:
   // Raw pointer. This worker runs synchronously.
   WebSocketImpl* mImpl;
 
-  ErrorResult& mRv;
+  nsresult mErrorCode;
 };
 
 } // namespace
 
 already_AddRefed<WebSocket>
 WebSocket::ConstructorCommon(const GlobalObject& aGlobal,
                              const nsAString& aUrl,
                              const Sequence<nsString>& aProtocols,
@@ -1265,19 +1276,20 @@ WebSocket::ConstructorCommon(const Globa
   }
 
   RefPtr<WebSocket> webSocket = new WebSocket(ownerWindow);
   RefPtr<WebSocketImpl> webSocketImpl = webSocket->mImpl;
 
   bool connectionFailed = true;
 
   if (NS_IsMainThread()) {
-    webSocketImpl->Init(aGlobal.Context(), principal, !!aTransportProvider,
-                        aUrl, protocolArray, EmptyCString(),
-                        0, 0, aRv, &connectionFailed);
+    aRv =
+      webSocketImpl->Init(aGlobal.Context(), principal, !!aTransportProvider,
+                          aUrl, protocolArray, EmptyCString(), 0, 0,
+                          &connectionFailed);
   } else {
     // In workers we have to keep the worker alive using a workerHolder in order
     // to dispatch messages correctly.
     if (!webSocketImpl->RegisterWorkerHolder()) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
 
@@ -1286,18 +1298,23 @@ WebSocket::ConstructorCommon(const Globa
     if (!JS::DescribeScriptedCaller(aGlobal.Context(), &file, &lineno,
                                     &column)) {
       NS_WARNING("Failed to get line number and filename in workers.");
     }
 
     RefPtr<InitRunnable> runnable =
       new InitRunnable(webSocketImpl, !!aTransportProvider, aUrl,
                        protocolArray, nsDependentCString(file.get()), lineno,
-                       column, aRv, &connectionFailed);
+                       column, &connectionFailed);
     runnable->Dispatch(aRv);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return nullptr;
+    }
+
+    aRv = runnable->ErrorCode();
   }
 
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   // It can be that we have been already disconnected because the WebSocket is
   // gone away while we where initializing the webSocket.
@@ -1364,24 +1381,29 @@ WebSocket::ConstructorCommon(const Globa
     if (topWindow) {
       topInner = topWindow->GetCurrentInnerWindow();
     }
 
     if (topInner) {
       windowID = topInner->WindowID();
     }
 
-    webSocket->mImpl->AsyncOpen(principal, windowID, aTransportProvider,
-                                aNegotiatedExtensions, aRv);
+    aRv = webSocket->mImpl->AsyncOpen(principal, windowID, aTransportProvider,
+                                      aNegotiatedExtensions);
   } else {
     MOZ_ASSERT(!aTransportProvider && aNegotiatedExtensions.IsEmpty(),
                "not yet implemented");
     RefPtr<AsyncOpenRunnable> runnable =
-      new AsyncOpenRunnable(webSocket->mImpl, aRv);
+      new AsyncOpenRunnable(webSocket->mImpl);
     runnable->Dispatch(aRv);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return nullptr;
+    }
+
+    aRv = runnable->ErrorCode();
   }
 
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   // It can be that we have been already disconnected because the WebSocket is
   // gone away while we where initializing the webSocket.
@@ -1462,61 +1484,53 @@ WebSocket::DisconnectFromOwner()
 
   DontKeepAliveAnyMore();
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketImpl:: initialization
 //-----------------------------------------------------------------------------
 
-void
+nsresult
 WebSocketImpl::Init(JSContext* aCx,
                     nsIPrincipal* aPrincipal,
                     bool aIsServerSide,
                     const nsAString& aURL,
                     nsTArray<nsString>& aProtocolArray,
                     const nsACString& aScriptFile,
                     uint32_t aScriptLine,
                     uint32_t aScriptColumn,
-                    ErrorResult& aRv,
                     bool* aConnectionFailed)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aPrincipal);
 
   mService = WebSocketEventService::GetOrCreate();
 
   // We need to keep the implementation alive in case the init disconnects it
   // because of some error.
   RefPtr<WebSocketImpl> kungfuDeathGrip = this;
 
   // Attempt to kill "ghost" websocket: but usually too early for check to fail
-  aRv = mWebSocket->CheckInnerWindowCorrectness();
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
+  nsresult rv = mWebSocket->CheckInnerWindowCorrectness();
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // Shut down websocket if window is frozen or destroyed (only needed for
   // "ghost" websockets--see bug 696085)
   if (!mWorkerPrivate) {
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (NS_WARN_IF(!os)) {
-      aRv.Throw(NS_ERROR_FAILURE);
-      return;
+      return NS_ERROR_FAILURE;
     }
 
-    aRv = os->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC, true);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
-
-    aRv = os->AddObserver(this, DOM_WINDOW_FROZEN_TOPIC, true);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
+    rv = os->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC, true);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = os->AddObserver(this, DOM_WINDOW_FROZEN_TOPIC, true);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (mWorkerPrivate) {
     mScriptFile = aScriptFile;
     mScriptLine = aScriptLine;
     mScriptColumn = aScriptColumn;
   } else {
     MOZ_ASSERT(aCx);
@@ -1535,28 +1549,23 @@ WebSocketImpl::Init(JSContext* aCx,
   // If we don't have aCx, we are window-less, so we don't have a
   // inner-windowID. This can happen in sharedWorkers and ServiceWorkers or in
   // DedicateWorkers created by JSM.
   if (aCx) {
     mInnerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(aCx);
   }
 
   // parses the url
-  aRv = ParseURL(PromiseFlatString(aURL));
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
+  rv = ParseURL(PromiseFlatString(aURL));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocument> originDoc = mWebSocket->GetDocumentIfCurrent();
   if (!originDoc) {
-    nsresult rv = mWebSocket->CheckInnerWindowCorrectness();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      aRv.Throw(rv);
-      return;
-    }
+    rv = mWebSocket->CheckInnerWindowCorrectness();
+    NS_ENSURE_SUCCESS(rv, rv);
   }
   mOriginDocument = do_GetWeakReference(originDoc);
 
   if (!mIsServerSide) {
     nsCOMPtr<nsIURI> uri;
     {
       nsresult rv = NS_NewURI(getter_AddRefs(uri), mURI);
 
@@ -1569,51 +1578,47 @@ WebSocketImpl::Init(JSContext* aCx,
 
     // The 'real' nsHttpChannel of the websocket gets opened in the parent.
     // Since we don't serialize the CSP within child and parent and also not
     // the context, we have to perform content policy checks here instead of
     // AsyncOpen2().
     // Please note that websockets can't follow redirects, hence there is no
     // need to perform a CSP check after redirects.
     int16_t shouldLoad = nsIContentPolicy::ACCEPT;
-    aRv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_WEBSOCKET,
-                                    uri,
-                                    aPrincipal,
-                                    originDoc,
-                                    EmptyCString(),
-                                    nullptr,
-                                    &shouldLoad,
-                                    nsContentUtils::GetContentPolicy(),
-                                    nsContentUtils::GetSecurityManager());
-
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
+    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_WEBSOCKET,
+                                   uri,
+                                   aPrincipal,
+                                   originDoc,
+                                   EmptyCString(),
+                                   nullptr,
+                                   &shouldLoad,
+                                   nsContentUtils::GetContentPolicy(),
+                                   nsContentUtils::GetSecurityManager());
+    NS_ENSURE_SUCCESS(rv, rv);
 
     if (NS_CP_REJECTED(shouldLoad)) {
       // Disallowed by content policy
-      aRv.Throw(NS_ERROR_CONTENT_BLOCKED);
-      return;
+      return NS_ERROR_CONTENT_BLOCKED;
     }
   }
 
   // Potentially the page uses the CSP directive 'upgrade-insecure-requests'.
   // In such a case we have to upgrade ws: to wss: and also update mSecure
   // to reflect that upgrade. Please note that we can not upgrade from ws:
   // to wss: before performing content policy checks because CSP needs to
   // send reports in case the scheme is about to be upgraded.
   if (!mIsServerSide && !mSecure && originDoc &&
       originDoc->GetUpgradeInsecureRequests(false)) {
     // let's use the old specification before the upgrade for logging
     NS_ConvertUTF8toUTF16 reportSpec(mURI);
 
     // upgrade the request from ws:// to wss:// and mark as secure
     mURI.ReplaceSubstring("ws://", "wss://");
     if (NS_WARN_IF(mURI.Find("wss://") != 0)) {
-      return;
+      return NS_OK;
     }
     mSecure = true;
 
     const char16_t* params[] = { reportSpec.get(), u"wss" };
     CSP_LogLocalizedStr(u"upgradeInsecureRequest",
                         params, ArrayLength(params),
                         EmptyString(), // aSourceFile
                         EmptyString(), // aScriptSample
@@ -1651,95 +1656,86 @@ WebSocketImpl::Init(JSContext* aCx,
 
         if (!isNullPrincipal) {
           break;
         }
 
         if (!innerWindow) {
           innerWindow = do_QueryInterface(globalObject);
           if (NS_WARN_IF(!innerWindow)) {
-            aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-            return;
+            return NS_ERROR_DOM_SECURITY_ERR;
           }
         }
 
         nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
           innerWindow->GetScriptableParent();
         if (NS_WARN_IF(!parentWindow)) {
-          aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-          return;
+          return NS_ERROR_DOM_SECURITY_ERR;
         }
 
         nsCOMPtr<nsPIDOMWindowInner> currentInnerWindow =
           parentWindow->GetCurrentInnerWindow();
         if (NS_WARN_IF(!currentInnerWindow)) {
-          aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-          return;
+          return NS_ERROR_DOM_SECURITY_ERR;
         }
 
         // We are at the top. Let's see if we have an opener window.
         if (innerWindow == currentInnerWindow) {
           ErrorResult error;
           parentWindow =
             nsGlobalWindow::Cast(innerWindow)->GetOpenerWindow(error);
           if (NS_WARN_IF(error.Failed())) {
             error.SuppressException();
-            aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-            return;
+            return NS_ERROR_DOM_SECURITY_ERR;
           }
 
           if (!parentWindow) {
             break;
           }
 
           currentInnerWindow = parentWindow->GetCurrentInnerWindow();
           if (NS_WARN_IF(!currentInnerWindow)) {
-            aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-            return;
+            return NS_ERROR_DOM_SECURITY_ERR;
           }
 
           MOZ_ASSERT(currentInnerWindow != innerWindow);
         }
 
         innerWindow = currentInnerWindow;
 
         nsCOMPtr<nsIDocument> document = innerWindow->GetExtantDoc();
         if (NS_WARN_IF(!document)) {
-          aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-          return;
+          return NS_ERROR_DOM_SECURITY_ERR;
         }
 
         principal = document->NodePrincipal();
       }
     }
 
     if (principal) {
       principal->GetURI(getter_AddRefs(originURI));
     }
 
     if (originURI) {
       bool originIsHttps = false;
-      aRv = originURI->SchemeIs("https", &originIsHttps);
-      if (NS_WARN_IF(aRv.Failed())) {
-        return;
-      }
+      rv = originURI->SchemeIs("https", &originIsHttps);
+      NS_ENSURE_SUCCESS(rv, rv);
+
       if (originIsHttps) {
-        aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
-        return;
+        return NS_ERROR_DOM_SECURITY_ERR;
       }
     }
   }
 
   // Assign the sub protocol list and scan it for illegal values
   for (uint32_t index = 0; index < aProtocolArray.Length(); ++index) {
     for (uint32_t i = 0; i < aProtocolArray[index].Length(); ++i) {
       if (aProtocolArray[index][i] < static_cast<char16_t>(0x0021) ||
           aProtocolArray[index][i] > static_cast<char16_t>(0x007E)) {
-        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-        return;
+        return NS_ERROR_DOM_SYNTAX_ERR;
       }
     }
 
     if (!mRequestedProtocolList.IsEmpty()) {
       mRequestedProtocolList.AppendLiteral(", ");
     }
 
     AppendUTF16toUTF8(aProtocolArray[index], mRequestedProtocolList);
@@ -1748,55 +1744,54 @@ WebSocketImpl::Init(JSContext* aCx,
   // the constructor should throw a SYNTAX_ERROR only if it fails to parse the
   // url parameter, so don't throw if InitializeConnection fails, and call
   // onerror/onclose asynchronously
   if (NS_FAILED(InitializeConnection(aPrincipal))) {
     *aConnectionFailed = true;
   } else {
     *aConnectionFailed = false;
   }
+
+  return NS_OK;
 }
 
-void
+nsresult
 WebSocketImpl::AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
                          nsITransportProvider* aTransportProvider,
-                         const nsACString& aNegotiatedExtensions,
-                         ErrorResult& aRv)
+                         const nsACString& aNegotiatedExtensions)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
   MOZ_ASSERT_IF(!aTransportProvider, aNegotiatedExtensions.IsEmpty());
 
   nsCString asciiOrigin;
-  aRv = nsContentUtils::GetASCIIOrigin(aPrincipal, asciiOrigin);
-  if (NS_WARN_IF(aRv.Failed())) {
-    return;
-  }
+  nsresult rv = nsContentUtils::GetASCIIOrigin(aPrincipal, asciiOrigin);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   if (aTransportProvider) {
-    aRv = mChannel->SetServerParameters(aTransportProvider, aNegotiatedExtensions);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
+    rv = mChannel->SetServerParameters(aTransportProvider,
+                                       aNegotiatedExtensions);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   ToLowerCase(asciiOrigin);
 
   nsCOMPtr<nsIURI> uri;
   if (!aTransportProvider) {
-    aRv = NS_NewURI(getter_AddRefs(uri), mURI);
-    MOZ_ASSERT(!aRv.Failed());
+    rv = NS_NewURI(getter_AddRefs(uri), mURI);
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 
-  aRv = mChannel->AsyncOpen(uri, asciiOrigin, aInnerWindowID, this, nullptr);
-  if (NS_WARN_IF(aRv.Failed())) {
-    aRv.Throw(NS_ERROR_CONTENT_BLOCKED);
-    return;
+  rv = mChannel->AsyncOpen(uri, asciiOrigin, aInnerWindowID, this, nullptr);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return NS_ERROR_CONTENT_BLOCKED;
   }
 
   mInnerWindowID = aInnerWindowID;
+
+  return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketImpl methods:
 //-----------------------------------------------------------------------------
 
 class nsAutoCloseWS final
 {