Files
cypress/packages/server/lib/util/network_failures.js
Zach Bloomquist 6b1d686ed2 Don't send Cypress error HTML on network errors (#4105)
* retry requests, basic e2e test

* basic e2e test for chrome behavior

* don't use timeouts to test

* some minor cleanup

* validate google chrome's retry behavior w/ a proxy

* get retries on network errors workin

* cleanup

* final changes before switching approach

* Reverting previous approach in request.coffee, server.coffee

* add retryOnNetworkFailure

* now works with retryOnStatusCodeFailure

* retry 4 times in addition to the 1 initial attempt

* add tests for subresources

* much improved error handling

* have the e2e test really work

* e2e baseurl check

* retry baseurl check

* remove special handling for node 8.2.1 bug

* WIP: continue making progress building out request retry

- swap out passthrough’s for pumpify / duplexify / pump
- clean up error handling / messaging / retry logic

* pipe clientrequest events

* buffer req body to disk, restore error handling/retrying

* don't bubble up errors from failed attempts

* actually pipe reqstream, oops

* add some e2e tests for request body

* revert lib/request.coffee to 7be1051

* add almost-working lazy-stream

* manually fire the 'pipe' event on the reqStream to copy headers to the outgoing message

- restore the ‘error’ propagation so that all tests pass for now

* cleanup leaking 'undefined' into stdout, causing failing e2e tests

- do not set onWarning as a property of project, just pass as an
argument

* add new options to request_spec, deduplicate default opts

* use stream buffer in request.coffee

* revert request.coffee

* last stream_buffer changes before removing fs stuff

* remove fs stuff from stream_buffer, add stream piping tests

* it works! :tada::tada:🎉 using duplexify to separate delayStream and reqBodyBuffer

* retry for .5s max on ECONNREFUSED

* add error codes

* don't timeout proxied requests

* restore baseurl check

* update new e2e tests

* make delay work with rp

* propagate clientresponse events

* removing tests that don't do anything now that we don't ESOCKETTIMEOUT on proxied requests

* add new visit, req options to index.d.ts

* don't fail on server-performance-test

* make retries with status code work again

* account for different stack trace in ci

* fix test

* retry https requests

* add tests for https passthru retries working

* clean up error handling for https-proxy

* fix failing https-proxy tests, tweak agent error handling to prevent multiple callbacks

* make expectedExitCode actual vs. expected in the correct order

* bump up e2e test timeout so it can retry and still work

* don't show cypress error page on network errors, gzip errors

* update tests

* clean up onWarning code

* add tests for incompatible options errors

* retry up to 500ms on proxied requests

* remove .only

* add tests for incompatible options errors

* remove .only

* maybe this will help it act more consistently

* help e2e test work in ci

* don't re-pipe the gzip response to client, the response is already gone

In the event that a gzip response has an error and we're not doing full injecting (ie, not buffering the response in memory), we can't just re-stream it.

By the time we do the second .pipe, the stream is already empty.

So, let's just error out anyways, which is what the browser would do (error).

* remove test for injecting into net error 500 pages in iframes

* update visit spec to expect an actual error, not Cypress HTML on visit timeouts

* update el snapshot

* don't reconnect on already made connections

* clarify naming

* wip: testing https proxy

* better debug calls

* WIP: getting proxy passthrough retry tests going

* handle retrying upstream proxy errors

- add tests for successfully retrying proxy errors and for unsuccessful
retries
- fix onClose errors when proxy connection is closed before enough data
is received
- fix not returning setTimeout correctly

* group related code accordingly

* do not build typescript by default, drop extension from main

* more TODO notes

* don't set a default NO_PROXY if NO_PROXY = ''

* debugging-proxy@2.0.0

* null out reqBodyBuffer when req finishes

* wip: retry in agent, not https-proxy [skip-ci]

* update https-proxy to use @packages/network retries

* retry after connection but before proxy tunnel established

* appease my linty overlords

* update https-proxy tests

* update agent specs, decided to still use tls.connect

it's easier to test and has less complexity

* test retrying HTTPS passthru

* debugging-proxy@2.0.1

* increase defaultCommandTimeout 100 -> 200 to prevent flake in CI

* auto formatting

* fix test to be dynamic and not rely on magic constants

* copy types field when linking proxy images, update packages/network types field

* linting

* add network index.js file

* linting

* improve error messaging experience when verifying base url

* only insert 1 new line

* fix failing test not binding to localhost

* removed test that's covered by e2e specs

* remove dash in 're-try'

* some cleanup for readability

* use allocUnsafe per perf

* unset NO_PROXY with an empty string

* move retry ensuring the baseUrl into url, cleanup some imperative code

* if the head is already present during connect, make connection, else wait for first head bytes

* minor formatting, clarity around conditions, naming

* rename retryInterval -> retryIntervals

* set defaults for requests during creation for clarity

* rename send -> sendPromise to pair better with sendStream

* use retryIntervals instead of juggling MAX_REQUEST_RETRIES

- ensure debug messages are consistent between request streams +
promises
- set static constants

* DRY up status check + network failure + retry logic

- keeps the debug logic identical between promises + streams
- ensures all logic paths are also consistent
- consolidates the pop’ing of intervals in a single place

* find / replace fail

* derp

* make the logic actually correct, set intervals as cloned defaults for recursive lookup

* pass arg correctly

* reduce debugging noise, formatting

* rename intervals -> delaysRemaining for clarity

* added unit tests around getDelayForRetry

* set retryIntervals as default options correctly, add unit tests

* using single line when debugging objects

* restore snapshot to match develop

* restore snapshot and move failing tests in e2e visit around momentarily...

* WIP: add the failing tests back in

* add tests for promise/stream that we don't retry on timeouts but do retry on resets

* use create entrypoint for tests

* pass requestTimeout from cy.visit(), remove hard coded request timeout

* s/requestTimeout/responseTimeout

* clean up how we initiate the request stream

* buffer resolve:url response before resolving promise

* only persist the buffer to memory once response finishes

* update visit spec to fail with ESOCKETTIMEDOUT

* use stream.PassThrough to buffer the response stream

* always buffer response stream

* de-commit those screenshots

* buffer forever - node's default is only to buffer 16kB

* some cleanup and renaming vars

* re-remove screenshots

* do all resolution login in on(end)

* update test to call the sendRequest callback

* update comment

* enable resolving:url to cancel currently in flight promises and abort pending requests

* add test for only having one request in flight at a time

* test currentPromisePhase too

* make tests fast again™️

* cleanup the coffeescript conversion, use common-tags, and use res.end to write final chunk

* add test ensuring that responseTimeout is passed correctly when resolving the url via cy.visit()

* micro-opt to check if err.code is property of zlib.constants

* always destroy the request socket when gzip fails as opposed to forwarding the broken bytes

* cleanup, formatting


Co-authored-by: Brian Mann <brian.mann86@gmail.com>
Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
2019-05-17 02:55:51 -04:00

41 lines
639 B
JavaScript

const { stripIndents, html } = require('common-tags')
const convertNewLinesToBr = (text) => {
return text.split('\n').join('<br />')
}
const fileErr = (url, status) => {
return stripIndents`
Cypress errored trying to serve this file from your system:
${url}
${status === 404 ? 'The file was not found.' : ''}
`
}
const wrap = (contents) => {
return html`
<!DOCTYPE html>
<html>
<body>
${convertNewLinesToBr(contents)}
</body>
</html>\
`
}
const get = (url, status) => {
const contents = fileErr(url, status)
return wrap(contents)
}
module.exports = {
fileErr,
wrap,
get,
}