Search code examples
vue.jswebpackwebpack-dev-serverhttp-proxy

webpack dev-server: Avoid proxy errors on HTTP errors returned from proxy target


I have a Vue.js project where I have configured a webpack dev-server to proxy all requests to the UI to my backend server. Here is the relevant part of vue.config.js:

devServer: {
    contentBase: PATHS.build,
    port: 9000,
    https: false,
    hot: true,
    progress: true,
    inline: true,
    watchContentBase: true,
    proxy: {
        '^/': {
            target: 'http://127.0.0.1:8089',
            secure: false
        },
    }
},

I've noticed that if the HTTP response code from http://127.0.0.1:8089 is anything other than 2xx then the proxy fails with the following error:

Proxy error: Could not proxy request /api/test from localhost:9000 to http://127.0.0.1:8089. See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (HPE_INVALID_CHUNK_SIZE).

This also causes the HTTP response code from the request to localhost:9000 to be 500 for any error and all the information about what went wrong on the server side is lost. This is problematic as I want to be able to extract information from error responses to display to the user.

I know it's possible to do because I had it working on an older Angular project which I think was using Webpack 3 (am now using Webpack 4). I tried copying all the dev-server config from this project but it just doesn't seem to work here!

EDIT: I was wrong. The Proxy error does not occur on every bad response but only for one of the requests which is a multipart file upload. Still unable to reproduce this in a smaller example to put on github though so struggling to pinpoint the cause.


Solution

  • I have finally found the problem, and I apologise, it was a lot more of a specific issue than I originally thought when I wrote the question.

    Issue was to do with a request which was proxied to another server using the Spring RestTemplate:

    e.g.

    @PostMapping("/upload")
        public ResponseEntity upload(@RequestParam("file") MultipartFile file)
            throws Exception {
            String baseUrl = serviceProperties.getAddress();
            HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
            return restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
        }
    

    The ResponseEntity returning from the rest template proxy contained the header "Connection: close" when the response was anything other than 200 which cause the connection to close and caused this request to fail to return anything which subsequently made the dev-server proxy fail on the UI.

    Fixed this by not passing the response headers from the rest template proxy to the response:

    @PostMapping("/upload")
        public ResponseEntity upload(@RequestParam("file") MultipartFile file)
            throws Exception {
            String baseUrl = serviceProperties.getAddress();
            HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
            ResponseEntity response = restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
            return new ResponseEntity<>(response.getBody(), response.getStatusCode());
        }