Search code examples
node.jsexpresshttpproxymiddleware

Http-proxy-middleware causes server to crash


I set up a proxy server for resource protected endpoints and I am using http-proxy-middleware. The problem is that when I get the response the server crashes with the following error:

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined.

Here is my api on server.mjs:

app.use('/api/someAPI', createProxyMiddleware({
    target: 'https://api.example.com',
    changeOrigin: true,
    pathRewrite: (path, req) => {
        const { arg1, arg2 } = req.query;
        return `/arg1/arg2}`;
    },
    selfHandleResponse: true,
    on: {
        proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
            try {
                if (!responseBuffer || typeof responseBuffer !== 'object' || responseBuffer.length === 0) {
                    throw new Error('Invalid or empty response from target server');
                }
                const response = responseBuffer.toString('utf8');

                res.json({ id: response });
            } catch (error) {
                res.status(500).json({ error: 'Failed to process response from target server' });
            }
        }),
    },
    headers: {
        Accept: "application/json",
        'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 Safari/605.1.15"
    }
}));

This is very strange because when I try to put a console.log after const response = responseBuffer.toString('utf8'); I see the desired result but the server crashes. I tried using Postman and server responds with a json with the desired data but server still crashes. I assume it has something to do with the responseBuffer, but still why it prints correctly?


Solution

  • responseInterceptor modifies the response, you cannot end the response from it, and you need to return modified response in one of the form the error says (string, buffer etc), and your handler doesn't return, hence the error complaining it got undefined instead.

    So, return modified response (here's an example of JSON, based on linked below JSON recipe. Note that you'll need to parse response, see the recipe):

        proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
            try {
                if (!responseBuffer || typeof responseBuffer !== 'object' || responseBuffer.length === 0) {
                    throw new Error('Invalid or empty response from target server');
                }
                const response = responseBuffer.toString('utf8');
    
                // to mutate JSON response, you'd use JSON.parse(response).. etc, see recipe example
    
                return JSON.stringify({ id: response });
            } catch (error) {
                res.statusCode = 500;
                return JSON.stringify({ error: 'Failed to process response from target server' });
            }
    
            // set some default return response
            return responseBuffer;
        }),
    

    see: Response Interceptor > Manipulate JSON responses (application/json)