An HTTP error is still an HTTP response.
Separate unsuccessful status codes from transport failure when diagnosing a browser request.


A panel fails to load and the test listens for requestfailed. Nothing arrives. The server returned an HTTP error response, so the browser did receive a response. The missing event is not proof that the request succeeded for the product. It means the test asked about the wrong failure boundary.
This guide uses Playwright's network documentation and Page events with two local invented requests. One returns a controlled HTTP 503. Another is deliberately aborted through a route. No customer endpoint or real outage is involved. We distinguish response status from transport completion.
Read the response status explicitly
The Page API documents request, response and requestfinished events for a completed request. HTTP error status codes are still responses and are not requestfailed events. A request can finish at the transport level while failing the application's promised behavior.
const pending = page.waitForResponse(response =>
response.url().endsWith('/demo-unavailable')
);
await page.getByRole('button', { name: 'Load demo panel' }).click();
const response = await pending;
expect(response.status()).toBe(503);
await expect(page.getByRole('status')).toHaveText('Demo service unavailable');This snippet assumes a local fixture with the named button and a server returning that controlled status. The UI reports the error deliberately. A 503 assertion is correct for this negative specimen; it is not a reason to accept 503 in a real happy path.
Put the response wait before the initiating action so the fast response remains tied to that case. Choose the endpoint and request identity from the feature contract. A broad response listener can accidentally observe a different request and turn unrelated traffic into evidence.
Use requestfailed for its own question
A requestfailed event describes failure to obtain a normal completed response, such as a transport problem. Our second specimen uses route.abort() to force that boundary. The handler confirms an event for the selected local URL and records a failure description without treating the wording as a cross-browser constant.
An aborted request is not a server-generated HTTP 503. Keep separate test names and expected UI behavior. If both cases lead to a useful retry message in the real product, test that requirement in each setup rather than merging the cause labels.
Do not infer an exact production cause from one event. A recorded transport error can guide investigation, but it does not by itself identify the failing server, network hop or policy. Combine the relevant request, response and application evidence within the permitted environment.
Do not turn transport completion into business success
A response may contain a valid status and still carry the wrong record or an error body. Status is one piece of the contract. Check the content and user-facing state required for the journey, while keeping this demonstration's claim narrow.
The local server counts a completed 503 response and the test confirms it did not generate requestfailed for that URL. The aborted case generates requestfailed instead. These observed differences validate event semantics; they do not benchmark reliability or reproduce an external outage.
Avoid adding repeated actions merely because an error event was absent. Repeated clicks can create duplicate operations when the server has already received a request. First identify which boundary failed and whether the product allows a retry.
Keep the failure vocabulary useful
Record endpoint, expected status or transport event, UI result and what remains unknown. This makes a report more useful than a single label called Network failed. Protect request URLs and payloads that contain private record details before sharing artifacts.
AnyTest describes reviewable end-to-end tests created after exploring an application. Ask whether a proposed error check watches the right event and verifies the intended recovery state. No specific AnyTest network implementation is claimed. Good diagnosis starts by separating an unsuccessful response from no completed response.
Common questions
Does HTTP 503 automatically fire requestfailed?
No. An HTTP error status is still a response; inspect its status explicitly.
Does requestfinished prove business success?
No. Transport completion is separate from status, content and the product outcome.