My application uses an end-to-end testing framework (Cypress) that outputs results in the
terminal. When testing changes to frontend code, I use the Vue dev server's
proxy
option to route API requests to a remote backend server.
Due to the high load of requests pummeling this test server, our application
frontend expects certain requests to fall through, and it is able to
intelligently handle retrying a given failed API call. However, the proxy
handler doesn't know this, and as a result the console log becomes cluttered
with ECONNRESET
proxy errors, as can be seen below.
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
✓ C22756 should be disabled when no events exist (8018ms)
✓ C22757 should be clickable when events exist (2250ms)
Widget Settings
Proxy error: Could not proxy request /api/XXXXXX from local.myapp.io:3000 to https://myapp-dev.appspot.com.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
✓ C22758 should have name, date range, and account fields (2435ms)
These errors can get quite verbose and tend to hide/obscure the more laconic test output, making it difficult to scan and nearly impossible to copy effectively.
Is there any way to suppress these error messages from the dev server/proxy handler? Ideally, there would be some form of configuration in an NPM script or the Vue/Webpack config JS file that would allow me to ignore or hide these errors just when running our test suite.
For reference, here is the config object being passed to the vue.config.js
file's devServer
property:
const config = {
allowedHosts: ['localhost', 'local.myapp.io'],
contentBase: path.join(__dirname, 'root/of/frontend/code'),
disableHostCheck: true,
historyApiFallback: true,
https: {
cert: LocalDevCert.getCert(),
key: LocalDevCert.getKey()
},
port: 3000,
proxy: {
'^(?!/(js|modules|img))': {
target: 'https://myapp-dev.appspot.com',
cookieDomainRewrite: 'local.myapp.io',
changeOrigin: true,
secure: true,
bypass (req, res) {
const xsrfToken = uuid();
if (req.headers.accept && req.headers.accept.includes('html')) {
res.cookie('MyXSRFToken', xsrfToken);
res.cookie('MyXSRFToken_C80', xsrfToken);
return '/index.html';
}
if (req.method === 'GET' && req.url.includes('login') && !req.url.includes('google')) {
res.cookie('MyXSRFToken', xsrfToken);
res.cookie('MyXSRFToken_C80', xsrfToken);
return '/';
}
}
}
},
public: 'local.myapp.io:3000'
};
I have tried:
- Using the devServer.client.logging configuration option, but this only changes what is shown in the browser console (not the command-line terminal).
- Adding the logLevel configuration option to the corresponding proxy configuration object (i.e. object with key
^(?!/(js|modules|img))
above), but this only seems to increase the amount of logging (info as well as errors).
I suspect something needs to be suppressed at a lower level, and perhaps some bash-script magic is the only plausible solution.
CodePudding user response:
You could add a filter at the top of the test, or globally in /cypress/support/index.js
.
Cypress.on('window:before:load', window => {
const originalConsoleLog = window.console.log;
window.console.log = (msg) => {
const isProxyError = msg.includes('ECONNRESET') || msg.startsWith('Proxy error:');
if (!isProxyError) {
originalConsoleLog(msg)
}
}
})
CodePudding user response:
The workaround that I eventually settled on was intercepting process.stdout.write
in the Javascript file that configured and ran the dev server/tests. Since our test
command is implemented as a Vue CLI plugin, I could just put the override function in that plugin's module.exports
as follows:
module.exports = (api, options) => {
api.registerCommand(
'customTestCommand',
{
description: 'A test command for posting on Stack Overflow',
usage: 'vue-cli-service customTestCommand [options]',
options: {
'--headless': 'run in headless mode without GUI'
...
}
},
async (args, rawArgs) => {
// Do other setup work here
process.stdout.write = (function (write) {
let clearBlankLine = false;
return function (...args) {
const string = args[0];
const isProxyError = !!string.match(/Proxy error:|ECONNRESET/);
const hasContent = !!string.trim();
if (isProxyError) {
clearBlankLine = true;
return;
}
if (!clearBlankLine || hasContent) {
write.apply(process.stdout, args);
}
clearBlankLine = false;
};
}(process.stdout.write));
// Wait to run your actual dev server process and test commands
// Until here.
}
);
};
This maintains all coloring, spacing, history clearing, etc. on the command line output, but any line that has the terms Proxy Error
or ECONNRESET
are removed. You can customize the regex to your specific needs.
For a more detailed example of intercepting both stdout and stderr, as well as redirecting those outputs to different locations (e.g. files), see the following Github gist by Ben Buckman that inspired my solution: https://gist.github.com/benbuckman/2758563