Proper way to handle error
pkropachev opened this issue · 2 comments
pkropachev commented
Hi!
I'm trying to handle error proxy.on('error', ...), but for some reason writeHead() method is not available for response.
Could you please advice what proper way to handle error, e.g. in case target is not available?
import { program, InvalidArgumentError } from 'commander';
import httpProxy from 'http-proxy';
import express from 'express';
function checkPort(value: string) {
const parsedValue = +value;
if (isNaN(parsedValue)) {
throw new InvalidArgumentError('Invalid int value.');
}
return parsedValue;
}
program
.option('-b ,--bind <address>', 'bind to this address (default: all interfaces)')
.option('-v ,--verbose', 'be verbose')
.argument('[port]', 'bind to this port', checkPort, 8000)
.allowExcessArguments(false)
.parse(process.argv);
const opts = program.opts();
const [port] = program.processedArgs;
const proxy = httpProxy.createProxyServer({});
proxy.on('proxyReq', (proxyReq, req) => {
console.log(`==> Request: ${req.socket.remoteAddress} - - "${req.method} ${req.url} HTTP/${req.httpVersion}"`);
if (opts.verbose) {
console.log('Headers:\n', JSON.stringify(req.headers, null, 2));
}
proxyReq.setHeader('User-Agent', 'http-proxy/1.0.0'); // Override User-Agent
console.log(`<== Request: ${proxyReq.host} - - "${proxyReq.method} ${proxyReq.path}"`);
if (opts.verbose) {
console.log('Headers:\n', JSON.stringify(proxyReq.getHeaders(), null, 2));
console.log(proxyReq);
}
});
proxy.on('proxyRes', (proxyRes) => {
console.log(
`==> Response: ${proxyRes.socket.remoteAddress} - - code ${proxyRes.statusCode}, message ${proxyRes.statusMessage}`,
);
if (opts.verbose) {
console.log('Headers:\n', JSON.stringify(proxyRes.headers, null, 2));
}
});
proxy.on('error', (err, res) => {
console.log('Error:', err.message);
// Handle error here, send response to requester
});
const app = express();
app
.get('*', (req, res) => {
const origin_url = new URL(req.url).host;
proxy.web(req, res, { target: `${req.protocol}://${origin_url}` });
})
.listen(port, opts.bind);
const host = opts.bind ? opts.bind : '::';
console.log(`Serving HTTP proxy on ${host} port ${port} ...`);Thanks!
mikejpeters commented
I think the res parameter is the 3rd parameter in the error callback (not the 2nd):
proxyServer.on('error', (error, req, res) => {
if (res instanceof ServerResponse) {
res.writeHead(502, {
'Content-Type': 'text/plain',
});
}
res.end('Something went wrong while proxying the request.');
});The typings for this library (@types/http-proxy) indicate that the res param is type ServerResponse<IncomingMessage> | net.Socket, and I assume it will never actually be a Socket unless ws is set to true, but I added the instanceof check in my case so typescript wouldn't complain
pkropachev commented
Thanks @mikejpeters for your reply! Yes, I did it in the same way.
proxy.on('error', (err, _req, unknownRes) => {
console.log('Error:', err.message);
const res = unknownRes as ServerResponse;
res.writeHead(500, { 'Content-Type': 'text-plain' });
res.end(err.message);
});