diff --git a/dom/base/test/unit/test_error_codes.js b/dom/base/test/unit/test_error_codes.js index 72b9e371d195..73c893c512e6 100644 --- a/dom/base/test/unit/test_error_codes.js +++ b/dom/base/test/unit/test_error_codes.js @@ -3,28 +3,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -var gExpectedStatus = null; -var gNextTestFunc = null; - var prefs = Services.prefs; -var asyncXHR = { - load() { - var request = new XMLHttpRequest(); - request.open("GET", "http://localhost:4444/test_error_code.xml", true); +function asyncXHR(expectedStatus, nextTestFunc) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "http://localhost:4444/test_error_code.xml", true); - var self = this; - request.addEventListener("error", function (event) { - self.onError(event); - }); - request.send(null); - }, - onError: function doAsyncRequest_onError(event) { + var sawError = false; + xhr.addEventListener("loadend", function doAsyncRequest_onLoad(event) { + Assert.ok(sawError, "Should have received an error"); + nextTestFunc(); + }); + xhr.addEventListener("error", function doAsyncRequest_onError(event) { var request = event.target.channel.QueryInterface(Ci.nsIRequest); - Assert.equal(request.status, gExpectedStatus); - gNextTestFunc(); - }, -}; + Assert.equal(request.status, expectedStatus); + sawError = true; + }); + xhr.send(null); +} function run_test() { do_test_pending(); @@ -41,10 +37,8 @@ function run_test_pt1() { // We always resolve localhost as it's hardcoded without the following pref: prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); - gExpectedStatus = Cr.NS_ERROR_OFFLINE; - gNextTestFunc = run_test_pt2; dump("Testing error returned by async XHR when the network is offline\n"); - asyncXHR.load(); + asyncXHR(Cr.NS_ERROR_OFFLINE, run_test_pt2); } // connection refused @@ -53,10 +47,8 @@ function run_test_pt2() { prefs.clearUserPref("network.dns.offline-localhost"); prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); - gExpectedStatus = Cr.NS_ERROR_CONNECTION_REFUSED; - gNextTestFunc = end_test; dump("Testing error returned by aync XHR when the connection is refused\n"); - asyncXHR.load(); + asyncXHR(Cr.NS_ERROR_CONNECTION_REFUSED, end_test); } function end_test() { diff --git a/dom/xhr/XMLHttpRequest.cpp b/dom/xhr/XMLHttpRequest.cpp index a331de6ffe03..f6bd1e18c7d1 100644 --- a/dom/xhr/XMLHttpRequest.cpp +++ b/dom/xhr/XMLHttpRequest.cpp @@ -7,9 +7,12 @@ #include "XMLHttpRequest.h" #include "XMLHttpRequestMainThread.h" #include "XMLHttpRequestWorker.h" +#include "mozilla/Logging.h" #include "mozilla/net/CookieJarSettings.h" #include "nsGlobalWindowInner.h" +mozilla::LazyLogModule gXMLHttpRequestLog("XMLHttpRequest"); + namespace mozilla::dom { /* static */ diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index c4197c5b5d97..c34a9a788a65 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -111,6 +111,8 @@ # undef CreateFile #endif +extern mozilla::LazyLogModule gXMLHttpRequestLog; + using namespace mozilla::net; namespace mozilla::dom { @@ -206,6 +208,7 @@ XMLHttpRequestMainThread::XMLHttpRequestMainThread( mRequestSentTime(0), mTimeoutMilliseconds(0), mErrorLoad(ErrorType::eOK), + mErrorLoadDetail(NS_OK), mErrorParsingXML(false), mWaitingForOnStopRequest(false), mProgressTimerIsActive(false), @@ -909,29 +912,43 @@ void XMLHttpRequestMainThread::GetStatusText(nsACString& aStatusText, } } -void XMLHttpRequestMainThread::TerminateOngoingFetch() { +void XMLHttpRequestMainThread::TerminateOngoingFetch(nsresult detail) { if ((mState == XMLHttpRequest_Binding::OPENED && mFlagSend) || mState == XMLHttpRequest_Binding::HEADERS_RECEIVED || mState == XMLHttpRequest_Binding::LOADING) { - CloseRequest(); + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Info, + ("%p TerminateOngoingFetch(0x%" PRIx32 ")", this, + static_cast(detail))); + CloseRequest(detail); } } -void XMLHttpRequestMainThread::CloseRequest() { +void XMLHttpRequestMainThread::CloseRequest(nsresult detail) { mWaitingForOnStopRequest = false; mErrorLoad = ErrorType::eTerminated; + mErrorLoadDetail = detail; if (mChannel) { mChannel->CancelWithReason(NS_BINDING_ABORTED, "XMLHttpRequestMainThread::CloseRequest"_ns); } - if (mTimeoutTimer) { - mTimeoutTimer->Cancel(); - } + CancelTimeoutTimer(); } void XMLHttpRequestMainThread::CloseRequestWithError( const ProgressEventType aType) { - CloseRequest(); + MOZ_LOG( + gXMLHttpRequestLog, LogLevel::Debug, + ("%p CloseRequestWithError(%hhu)", this, static_cast(aType))); + nsresult detail = NS_ERROR_DOM_UNKNOWN_ERR; + if (aType == ProgressEventType::abort) { + detail = NS_ERROR_DOM_ABORT_ERR; + } else if (aType == ProgressEventType::error) { + detail = NS_ERROR_DOM_NETWORK_ERR; + } else if (aType == ProgressEventType::timeout) { + detail = NS_ERROR_DOM_TIMEOUT_ERR; + } + + CloseRequest(detail); ResetResponse(); @@ -968,11 +985,20 @@ void XMLHttpRequestMainThread::CloseRequestWithError( void XMLHttpRequestMainThread::RequestErrorSteps( const ProgressEventType aEventType, const nsresult aOptionalException, ErrorResult& aRv) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p RequestErrorSteps(%hhu,0x%" PRIx32 ")", this, + static_cast(aEventType), + static_cast(aOptionalException))); + + // Cancel our timers first before setting our state to done, so we don't + // trip any assertions if one fires and asserts that state != done. + CancelTimeoutTimer(); + CancelSyncTimeoutTimer(); + StopProgressEventTimer(); + // Step 1 mState = XMLHttpRequest_Binding::DONE; - StopProgressEventTimer(); - // Step 2 mFlagSend = false; @@ -1012,21 +1038,23 @@ void XMLHttpRequestMainThread::RequestErrorSteps( void XMLHttpRequestMainThread::Abort(ErrorResult& aRv) { NOT_CALLABLE_IN_SYNC_SEND_RV + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, ("%p Abort()", this)); AbortInternal(aRv); } void XMLHttpRequestMainThread::AbortInternal(ErrorResult& aRv) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, ("%p AbortInternal()", this)); mFlagAborted = true; DisconnectDoneNotifier(); // Step 1 - TerminateOngoingFetch(); + TerminateOngoingFetch(NS_ERROR_DOM_ABORT_ERR); // Step 2 if ((mState == XMLHttpRequest_Binding::OPENED && mFlagSend) || mState == XMLHttpRequest_Binding::HEADERS_RECEIVED || mState == XMLHttpRequest_Binding::LOADING) { - RequestErrorSteps(ProgressEventType::abort, NS_OK, aRv); + RequestErrorSteps(ProgressEventType::abort, NS_ERROR_DOM_ABORT_ERR, aRv); } // Step 3 @@ -1278,6 +1306,15 @@ void XMLHttpRequestMainThread::DispatchProgressEvent( ProgressEvent::Constructor(aTarget, typeString, init); event->SetTrusted(true); + if (MOZ_LOG_TEST(gXMLHttpRequestLog, LogLevel::Debug)) { + nsAutoString type; + event->GetType(type); + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("firing %s event (%u,%u,%" PRIu64 ",%" PRIu64 ")", + NS_ConvertUTF16toUTF8(type).get(), aTarget == mUpload, + aTotal != -1, aLoaded, (aTotal == -1) ? 0 : aTotal)); + } + DispatchOrStoreEvent(aTarget, event); // If we're sending a load, error, timeout or abort event, then @@ -1487,7 +1524,7 @@ void XMLHttpRequestMainThread::Open(const nsACString& aMethod, } // Step 10 - TerminateOngoingFetch(); + TerminateOngoingFetch(NS_OK); // Step 11 // timeouts are handled without a flag @@ -1835,6 +1872,7 @@ XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request) { request->GetStatus(&status); if (mErrorLoad == ErrorType::eOK && NS_FAILED(status)) { mErrorLoad = ErrorType::eRequest; + mErrorLoadDetail = status; } // Upload phase is now over. If we were uploading anything, @@ -2105,7 +2143,7 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest* request, nsresult status) { if (status == NS_BINDING_ABORTED) { mFlagParseBody = false; IgnoredErrorResult rv; - RequestErrorSteps(ProgressEventType::abort, NS_OK, rv); + RequestErrorSteps(ProgressEventType::abort, NS_ERROR_DOM_ABORT_ERR, rv); ChangeState(XMLHttpRequest_Binding::UNSENT, false); return NS_OK; } @@ -2208,7 +2246,28 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest* request, nsresult status) { // reasons are that the user leaves the page or hits the ESC key. mErrorLoad = ErrorType::eUnreachable; + mErrorLoadDetail = status; mResponseXML = nullptr; + + // Handle network errors specifically per spec. + if (NS_ERROR_GET_MODULE(status) == NS_ERROR_MODULE_NETWORK) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p detected networking error 0x%" PRIx32 "\n", this, + static_cast(status))); + IgnoredErrorResult rv; + mFlagParseBody = false; + RequestErrorSteps(ProgressEventType::error, NS_ERROR_DOM_NETWORK_ERR, rv); + // RequestErrorSteps will not call ChangeStateToDone for sync XHRs, so we + // do so here to ensure progress events are sent and our state is sane. + if (mFlagSynchronous) { + ChangeStateToDone(wasSync); + } + return NS_OK; + } + + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p detected unreachable error 0x%" PRIx32 "\n", this, + static_cast(status))); } // If we're uninitialized at this point, we encountered an error @@ -2316,9 +2375,7 @@ void XMLHttpRequestMainThread::ChangeStateToDoneInternal() { mFlagSend = false; - if (mTimeoutTimer) { - mTimeoutTimer->Cancel(); - } + CancelTimeoutTimer(); // Per spec, fire the last download progress event, if any, // before readystatechange=4/done. (Note that 0-sized responses @@ -2706,6 +2763,7 @@ nsresult XMLHttpRequestMainThread::InitiateFetch( mChannel = nullptr; mErrorLoad = ErrorType::eChannelOpen; + mErrorLoadDetail = rv; // Per spec, we throw on sync errors, but not async. if (mFlagSynchronous) { @@ -2897,16 +2955,18 @@ void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody, // we have internal code relying on the channel being created in open(). if (!mChannel) { mErrorLoad = ErrorType::eChannelOpen; + mErrorLoadDetail = NS_ERROR_DOM_NETWORK_ERR; mFlagSend = true; // so CloseRequestWithError sets us to DONE. - aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR); + aRv = MaybeSilentSendFailure(mErrorLoadDetail); return; } // non-GET requests aren't allowed for blob. if (IsBlobURI(mRequestURL) && !mRequestMethod.EqualsLiteral("GET")) { mErrorLoad = ErrorType::eChannelOpen; + mErrorLoadDetail = NS_ERROR_DOM_NETWORK_ERR; mFlagSend = true; // so CloseRequestWithError sets us to DONE. - aRv = MaybeSilentSendFailure(NS_ERROR_DOM_NETWORK_ERR); + aRv = MaybeSilentSendFailure(mErrorLoadDetail); return; } @@ -2919,6 +2979,7 @@ void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody, // By default we don't have any upload, so mark upload complete. mUploadComplete = true; mErrorLoad = ErrorType::eOK; + mErrorLoadDetail = NS_OK; mLoadTotal = -1; nsCOMPtr uploadStream; nsAutoCString uploadContentType; @@ -3181,9 +3242,7 @@ void XMLHttpRequestMainThread::StartTimeoutTimer() { return; } - if (mTimeoutTimer) { - mTimeoutTimer->Cancel(); - } + CancelTimeoutTimer(); if (!mTimeoutMilliseconds) { return; @@ -3364,6 +3423,7 @@ nsresult XMLHttpRequestMainThread::OnRedirectVerifyCallback(nsresult result, } } else { mErrorLoad = ErrorType::eRedirect; + mErrorLoadDetail = result; } mNewRedirectChannel = nullptr; @@ -3522,6 +3582,13 @@ void XMLHttpRequestMainThread::HandleTimeoutCallback() { CloseRequestWithError(ProgressEventType::timeout); } +void XMLHttpRequestMainThread::CancelTimeoutTimer() { + if (mTimeoutTimer) { + mTimeoutTimer->Cancel(); + mTimeoutTimer = nullptr; + } +} + NS_IMETHODIMP XMLHttpRequestMainThread::Notify(nsITimer* aTimer) { if (mProgressNotifier == aTimer) { @@ -3625,6 +3692,7 @@ void XMLHttpRequestMainThread::HandleSyncTimeoutTimer() { CancelSyncTimeoutTimer(); Abort(); + mErrorLoadDetail = NS_ERROR_DOM_TIMEOUT_ERR; } void XMLHttpRequestMainThread::CancelSyncTimeoutTimer() { diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h index b248e0366401..b0cf3ced6ba3 100644 --- a/dom/xhr/XMLHttpRequestMainThread.h +++ b/dom/xhr/XMLHttpRequestMainThread.h @@ -333,7 +333,7 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest, void Abort() { IgnoredErrorResult rv; AbortInternal(rv); - MOZ_ASSERT(!rv.Failed()); + MOZ_ASSERT(!rv.Failed() || rv.ErrorCodeIs(NS_ERROR_DOM_ABORT_ERR)); } virtual void Abort(ErrorResult& aRv) override; @@ -409,6 +409,8 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest, void SetSource(UniquePtr aSource); + nsresult ErrorDetail() const { return mErrorLoadDetail; } + virtual uint16_t ErrorCode() const override { return static_cast(mErrorLoad); } @@ -680,6 +682,7 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest, nsCOMPtr mTimeoutTimer; void StartTimeoutTimer(); void HandleTimeoutCallback(); + void CancelTimeoutTimer(); nsCOMPtr mResumeTimeoutRunnable; @@ -692,6 +695,7 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest, void CancelSyncTimeoutTimer(); ErrorType mErrorLoad; + nsresult mErrorLoadDetail; bool mErrorParsingXML; bool mWaitingForOnStopRequest; bool mProgressTimerIsActive; @@ -715,9 +719,9 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest, /** * Close the XMLHttpRequest's channels. */ - void CloseRequest(); + void CloseRequest(nsresult detail); - void TerminateOngoingFetch(); + void TerminateOngoingFetch(nsresult detail); /** * Close the XMLHttpRequest's channels and dispatch appropriate progress diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp index 5ad96c5f27bb..7443da31d9c4 100644 --- a/dom/xhr/XMLHttpRequestWorker.cpp +++ b/dom/xhr/XMLHttpRequestWorker.cpp @@ -43,6 +43,8 @@ #include "mozilla/UniquePtr.h" +extern mozilla::LazyLogModule gXMLHttpRequestLog; + namespace mozilla::dom { /** @@ -117,6 +119,7 @@ class Proxy final : public nsIDOMEventListener { uint64_t mLastTotal; uint64_t mLastUploadLoaded; uint64_t mLastUploadTotal; + nsresult mLastErrorDetailAtLoadend; bool mIsSyncXHR; bool mLastLengthComputable; bool mLastUploadLengthComputable; @@ -150,6 +153,7 @@ class Proxy final : public nsIDOMEventListener { mLastTotal(0), mLastUploadLoaded(0), mLastUploadTotal(0), + mLastErrorDetailAtLoadend(NS_OK), mIsSyncXHR(false), mLastLengthComputable(false), mLastUploadLengthComputable(false), @@ -450,6 +454,7 @@ class EventRunnable final : public MainThreadProxyRunnable { bool mProgressEvent; bool mLengthComputable; nsresult mStatusResult; + nsresult mErrorDetail; // mScopeObj is used in PreDispatch only. We init it in our constructor, and // reset() in PreDispatch, to ensure that it's not still linked into the // runtime once we go off-thread. @@ -471,6 +476,7 @@ class EventRunnable final : public MainThreadProxyRunnable { mProgressEvent(true), mLengthComputable(aLengthComputable), mStatusResult(NS_OK), + mErrorDetail(NS_OK), mScopeObj(RootingCx(), aScopeObj) {} EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType, @@ -487,6 +493,7 @@ class EventRunnable final : public MainThreadProxyRunnable { mProgressEvent(false), mLengthComputable(0), mStatusResult(NS_OK), + mErrorDetail(NS_OK), mScopeObj(RootingCx(), aScopeObj) {} private: @@ -1047,6 +1054,8 @@ bool EventRunnable::PreDispatch(WorkerPrivate* /* unused */) { mStatus = xhr->GetStatus(rv); mStatusResult = rv.StealNSResult(); + mErrorDetail = xhr->ErrorDetail(); + xhr->GetStatusText(mStatusText, rv); MOZ_ASSERT(!rv.Failed()); @@ -1068,6 +1077,10 @@ bool EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { return true; } + if (mType.EqualsASCII(sEventStrings[STRING_loadend])) { + mProxy->mLastErrorDetailAtLoadend = mErrorDetail; + } + if (mType.EqualsASCII(sEventStrings[STRING_loadstart])) { if (mUploadEvent) { mProxy->mSeenUploadLoadStart = true; @@ -1164,6 +1177,15 @@ bool EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { event->SetTrusted(true); + if (MOZ_LOG_TEST(gXMLHttpRequestLog, LogLevel::Debug)) { + nsAutoString type; + event->GetType(type); + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p firing %s event (%u,%u,%" PRIu64 ",%" PRIu64 ")", + mProxy->mXHR.get(), NS_ConvertUTF16toUTF8(type).get(), + mUploadEvent, mLengthComputable, mLoaded, mTotal)); + } + target->DispatchEvent(*event); return true; @@ -1588,6 +1610,13 @@ void XMLHttpRequestWorker::DispatchPrematureAbortEvent( event->SetTrusted(true); + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p firing %s pre-abort event (%u,%u,%" PRIu64 ",%" PRIu64, this, + NS_ConvertUTF16toUTF8(aEventType).get(), aUploadTarget, + aUploadTarget ? mProxy->mLastUploadLengthComputable + : mProxy->mLastLengthComputable, + aUploadTarget ? mProxy->mLastUploadLoaded : mProxy->mLastLoaded, + aUploadTarget ? mProxy->mLastUploadTotal : mProxy->mLastTotal)); aTarget->DispatchEvent(*event); } @@ -1688,12 +1717,39 @@ void XMLHttpRequestWorker::SendInternal(const BodyExtractorBase* aBody, bool succeeded = NS_SUCCEEDED(autoSyncLoop->Run()); mStateData->mFlagSend = false; + // Throw appropriately If a sync XHR failed per spec's RequestErrorSteps + if (isSyncXHR && mProxy) { + nsresult error = mProxy->mLastErrorDetailAtLoadend; + if (error == NS_ERROR_DOM_ABORT_ERR) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Info, + ("%p throwing NS_ERROR_DOM_ABORT_ERR", this)); + aRv.Throw(error); + return; + } + if (error == NS_ERROR_DOM_TIMEOUT_ERR) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Info, + ("%p throwing NS_ERROR_DOM_TIMEOUT_ERR", this)); + aRv.Throw(error); + return; + } + if (error == NS_ERROR_DOM_NETWORK_ERR || + NS_ERROR_GET_MODULE(error) == NS_ERROR_MODULE_NETWORK) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Info, + ("%p throwing NS_ERROR_DOM_NETWORK_ERR (0x%" PRIx32 ")", this, + static_cast(error))); + aRv.Throw(NS_ERROR_DOM_NETWORK_ERR); + return; + } + } + // Don't clobber an existing exception that we may have thrown on aRv // already... though can there really be one? In any case, it seems to me // that this autoSyncLoop->Run() can never fail, since the StopSyncLoop call // for it will come from ProxyCompleteRunnable and that always passes true for // the second arg. if (!succeeded && !aRv.Failed()) { + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p SendInternal failed; throwing NS_ERROR_FAILURE", this)); aRv.Throw(NS_ERROR_FAILURE); } } @@ -1705,6 +1761,10 @@ void XMLHttpRequestWorker::Open(const nsACString& aMethod, ErrorResult& aRv) { mWorkerPrivate->AssertIsOnWorkerThread(); + MOZ_LOG(gXMLHttpRequestLog, LogLevel::Debug, + ("%p Open(%s,%s,%d)", this, nsAutoCString(aMethod).get(), + NS_ConvertUTF16toUTF8(aUrl).get(), aAsync)); + if (mCanceled) { aRv.ThrowUncatchableException(); return; diff --git a/dom/xhr/tests/test_XHR_timeout.js b/dom/xhr/tests/test_XHR_timeout.js index e5ab627efc34..1e75c1c1748a 100644 --- a/dom/xhr/tests/test_XHR_timeout.js +++ b/dom/xhr/tests/test_XHR_timeout.js @@ -96,7 +96,24 @@ RequestTracker.prototype = { }, this.resetAfter); } - req.send(null); + var gotException; + var expectTimeoutException = + !this.async && inWorker && this.timeLimit > 0 && this.timeLimit < 3000; + + try { + req.send(null); + } catch (e) { + gotException = e; + if (expectTimeoutException) { + ok(e.name == "TimeoutError", "Should be a TimeoutError"); + } + } + + if (gotException && !expectTimeoutException) { + ok(false, `expected no exception, got ${gotException}`); + } else if (!gotException && expectTimeoutException) { + ok(false, "expected timeout exception"); + } }, /** diff --git a/testing/web-platform/meta/xhr/response-body-errors.any.js.ini b/testing/web-platform/meta/xhr/response-body-errors.any.js.ini index f2313875bddb..aba81dcc3611 100644 --- a/testing/web-platform/meta/xhr/response-body-errors.any.js.ini +++ b/testing/web-platform/meta/xhr/response-body-errors.any.js.ini @@ -1,15 +1,8 @@ [response-body-errors.any.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [Asynchronous XMLHttpRequest should clear response on bad chunk] - expected: FAIL [response-body-errors.any.worker.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [Synchronous XMLHttpRequest should throw on bad chunk] - expected: FAIL - - [Asynchronous XMLHttpRequest should clear response on bad chunk] - expected: FAIL