cypress: Intercept with req.continue throws "Error: Socket closed before finished writing response"

Current behavior

Application behaviour

I have an Angular app which triggers multiple requests on the same endpoint:

  • 1st request happens when loading the page (it is crucial for the reproduction of this issue)
  • The 2nd and 3rd request happen upon interaction with the page, where the 2nd request will be cancelled because of the use of “switchMap”

Main issue

See test req.continue() / fails with Error "Socket closed before finished writing response"

In the cancelled request, we see the error CypressError: A callback was provided to intercept the upstream response, but a network error occurred while making the request: Error: Socket closed before finished writing response:

image

This error results in a failed test, if we call cy.wait('@myAlias') or even cy.wait(2000) (!)

If we don’t call cy.wait(…) then the error will be ignored and will only be visible in the console. To reproduce this add .only to the test "does not fail with "Error Socket closed before finished writing response", but should fail" and maybe run multiple times. A red, cancelled request should appear and the error is visible in the console when clicking on the red, cancelled request.

The same issue happens “consistentlyer 😉” when using req.on('response') instead of req.continue(..) and error is hidden inside the console:

image

In my setup I cannot use req.on('response') because it triggers other errors and issues (I think I saw it somehow mess up the order of interceptions in the command log?). After all req.continue() should just work fine.

Desired behavior

There is a benefit in this kind of failing test, so that we know that we should/could replace switchMap with exhaustMap to prevent multiple service calls. But this is not the main reason I created this ticket. Previously in Cypress 10.7.0 these tests would not fail and the error was probably just hidden.

I expect that the error gets either propagated in every situation and that it can be handled or ignored explicitly or that the error is ignored completely.

I see that using req.on(‘response’) would be more sense since this is called only before an actual response is sent to the browser. But in this scenario, both should just work fine. If the request was cancelled, Cypress shouldn’t care about sending a response anyway and it shouldn’t do anything in req.continue(…).

Test code to reproduce

https://github.com/mirobo/cypress-cloud-module-api

  • npm i
  • npm run start
  • npx cypress open
  • run test cancelled-request.cy.js (if failure doesn’t happen, rerun the test)

Cypress Version

12.8.1

Node version

v18.13.0

Operating System

Windows 10

Debug Logs

No response

Other

No response

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 17
  • Comments: 28 (12 by maintainers)

Commits related to this issue

Most upvoted comments

@Matthew-Turner-ptml @Gopala7721 @mirobo @mjhenkes I have solved this issue by changing the req.continue to

req.on('response', response => /* do something with the response */)

This on-trigger will only use responses sent back and will not fail on cancelled requests, because these will not trigger this on-response.

Because req.continue needs a valid response to work. https://docs.cypress.io/api/commands/intercept#Request-events

we are facing same issue after upgrading to cypress 12.13.0 please provide us the fix

Sure there are more critical issues to be fair and my workaround with patching Cypress still works with 12.17.1. But still… it’s 8 months now and to me Cypress’ intercept is a key feature…

I tought of writing code to temporarly just ignore this error by patching

C:.…\Cypress\Cache\12.10.0\Cypress\resources\app\node_modules\bluebird\js\release\util.js

…and as stupid as it sounds: Replacing

function tryCatcher() {
    try {
        var target = tryCatchTarget;
        tryCatchTarget = null;
        return target.apply(this, arguments);
    } catch (e) {
        errorObj.e = e;
        return errorObj;
    }
}

with

function tryCatcher() {
    try {
        var target = tryCatchTarget;
        tryCatchTarget = null;
        return target.apply(this, arguments);
    } catch (e) {
        errorObj.e = e;
		if(!`${e}`.includes('Socket closed before finished writing response')) {
			return errorObj;
		}
        // return errorObj;
    }
}

I’m hoping this bug gets fixed with the next release so I don’t have to go with this ugly hack, of which I don’t even know it does what I expect xD. But be my guest 😉