gatsby icon indicating copy to clipboard operation
gatsby copied to clipboard

The development proxy does not transfer non-200 HTTP codes and responses

Open jsalvata opened this issue 2 years ago • 1 comments

Preliminary Checks

  • [X] This issue is not a duplicate. Before opening a new issue, please search existing issues: https://github.com/gatsbyjs/gatsby/issues
  • [X] This issue is not a question, feature request, RFC, or anything other than a bug report directly related to Gatsby. Please post those things in GitHub Discussions: https://github.com/gatsbyjs/gatsby/discussions

Description

When using the embedded HTTP proxy to access an API as instructed in https://www.gatsbyjs.com/docs/api-proxy/, any non-200 responses from the remote server will be passed to the client as "500 Internal server error". The original response from the remote server is lost.

This has been reported in detail at least twice: https://github.com/gatsbyjs/gatsby/issues/34244 (moved to a discussion) https://github.com/gatsbyjs/gatsby/issues/33333 (closed following the release of Gatsby 4, in spite of dangkyokhoang having provided a solution)

Reproduction link and steps to reproduce can be found in the 2nd link above. I'll copy them over.

Reproduction Link

https://codesandbox.io/s/infallible-phoebe-69w1t?file=/src/pages/index.js

Steps to Reproduce

  1. Set proxy in gatsby-config.js
proxy: [
  {
    prefix: "/v3",
    url: "https://run.mocky.io"
  }
]
  1. yarn develop
  2. Try fetching this https://run.mocky.io/v3/99fc1661-4a34-4334-a123-ae9c02b33db4 which has 400 status code and {"error":1} response body.

Expected Result

Should receive 400 {"error":1}

Actual Result

Received 500 Internal Server Error

Environment

System:
    OS: macOS 12.5.1
    CPU: (10) x64 Apple M1 Pro
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 14.18.2 - ~/.nvm/versions/node/v14.18.2/bin/node
    npm: 8.19.1 - ~/.nvm/versions/node/v14.18.2/bin/npm
  Languages:
    Python: 2.7.17 - /usr/local/bin/python
  Browsers:
    Chrome: 105.0.5195.102
    Firefox: 101.0
    Safari: 15.6.1
  npmPackages:
    gatsby: ^4.22.0 => 4.22.0
    gatsby-plugin-image: ^2.22.0 => 2.22.0
    gatsby-plugin-manifest: ^4.22.0 => 4.22.0
    gatsby-plugin-mdx: ^4.1.0 => 4.1.0
    gatsby-plugin-react-helmet: ^5.22.0 => 5.22.0
    gatsby-plugin-sharp: ^4.22.0 => 4.22.0
    gatsby-plugin-sitemap: ^5.22.0 => 5.22.0
    gatsby-plugin-styled-components: ^5.22.0 => 5.22.0
    gatsby-source-filesystem: ^4.22.0 => 4.22.0
    gatsby-transformer-remark: ^5.22.0 => 5.22.0
    gatsby-transformer-sharp: ^4.22.0 => 4.22.0

Config Flags

No response

jsalvata avatar Sep 11 '22 13:09 jsalvata

I've submitted a pull request with dangkyokhoang's fix:

https://github.com/gatsbyjs/gatsby/pull/36590

jsalvata avatar Sep 11 '22 13:09 jsalvata

Looks like the pull request was denied and the original issue was closed. This is still an issue for me so I'm following this ticket in hopes for a fix.

bzmillerboy avatar Nov 25 '22 15:11 bzmillerboy

I have came with simple workaround. Based on mentioned patch

I wrote a function (extraced from patch) in my gatsby-config.js:

const got = require('got');
const report = require("gatsby-cli/lib/reporter");

function proxy(app, prefix, url) {
  app.use(`${prefix}/*`, (req, res) => {
    const proxiedUrl = url + req.originalUrl
    const {
      headers: { host, ...headers },
      method,
    } = req
    req
        .pipe(
            got
                .stream(proxiedUrl, {
                  headers,
                  method: method,
                  decompress: false,
                })
                .on(`response`, response =>
                    res.writeHead(response.statusCode || 200, response.headers)
                )
                .on(`error`, (err, _, response) => {
                  if (response = err.response) {
                    res.writeHead(response.statusCode || 400, response.headers)
                    res.end(response.rawBody)
                  } else {
                    const message = `Error when trying to proxy request "${req.originalUrl}" to "${proxiedUrl}"`

                    report.error(message, err)
                    res.sendStatus(500)
                  }
                })
        )
        .pipe(res)
  })
}

and changed proxy config in gatsby-config.js from:

 module.exports = {
   proxy: {
     prefix: "/api",
     url: "http://localhost:8080"
  }
}

to:

module.exports = {
  developMiddleware: (app) => {
    proxy(app, "/api", "http://localhost:8080");
  }
}

I hope this helps.

Ryszard-Trojnacki avatar Apr 21 '23 14:04 Ryszard-Trojnacki