Apollo-link: Handle error response depending on `Content-Type`

Created on 25 Mar 2018  ·  3Comments  ·  Source: apollographql/apollo-link

Default accept header is set to */*:

https://github.com/apollographql/apollo-link/blob/a79f47e8ae81ee2444d547315be61dbafea37dcb/packages/apollo-link-http-common/src/index.ts#L98

But we incorrectly assume that response is json, and tries to JSON.parse(bodyText), without checking bodyText's content-type.

https://github.com/apollographql/apollo-link/blob/a79f47e8ae81ee2444d547315be61dbafea37dcb/packages/apollo-link-http-common/src/index.ts#L123-L137

If your server returns a 403 text/plain for example:

HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=utf-8
Content-Length: 18
Date: Sun, 25 Mar 2018 20:08:00 GMT
Connection: keep-alive

Invalid CSRF token

Apollo throws a strange error:

overview.js:80369 Error: Network error: Unexpected token I in JSON at position 0
    at new ApolloError (overview.js:70404)
    at ObservableQuery.webpackJsonp.../../../../../public/next/next-apollo/node_modules/.registry.npmjs.org/apollo-client/2.2.0/node_modules/apollo-client/core/ObservableQuery.js.ObservableQuery.currentResult (overview.js:68953)
    at ProxyComponent.Query._this.getQueryResult (overview.js:52088)
    at ProxyComponent.webpackJsonp.../../../../../../node_modules/.registry.npmjs.org/react-apollo/2.1.0-rc.3/node_modules/react-apollo/Query.js.Query.render (overview.js:52184)
    at ProxyComponent.proxiedRender (main.js:38683)
    at finishClassComponent (main.js:30599)
    at updateClassComponent (main.js:30576)
    at beginWork (main.js:30951)
    at performUnitOfWork (main.js:32950)
    at workLoop (main.js:33014)

Expected Behavior

Actual Behavior

A _simple_ reproduction

Issue Labels

  • [ ] has-reproduction
  • [ ] feature
  • [ ] docs
  • [ ] blocking
  • [ ] good first issue

Most helpful comment

We run into this same issue (at Netflix) because of proxies that we sometimes have in front. We are currently thinking of wrapping fetch to handle this either in a reactive way:

const customFetch = (uri, options) => {
  return fetch(uri, options).catch(
    err => {
      // If it's our Content-Type issue from our proxy,
      // reformat the error to match Apollo
      throw new Error(...)
    }
};

const link = createHttpLink({ fetch: customFetch });

or in a proactive way -- we do the validation then pass it on.

All 3 comments

Bump. Just encountered same thing with 501 error. Error: Network error: Unexpected token N in JSON at position 0.

Looks like, your response is not a valid JSON. Try to check what your server is returning before this line:

console.log(bodyText);
return JSON.parse(bodyText);

We run into this same issue (at Netflix) because of proxies that we sometimes have in front. We are currently thinking of wrapping fetch to handle this either in a reactive way:

const customFetch = (uri, options) => {
  return fetch(uri, options).catch(
    err => {
      // If it's our Content-Type issue from our proxy,
      // reformat the error to match Apollo
      throw new Error(...)
    }
};

const link = createHttpLink({ fetch: customFetch });

or in a proactive way -- we do the validation then pass it on.

Was this page helpful?
0 / 5 - 0 ratings