admin管理员组

文章数量:1334805

I am using graphql in my application and it sends the following response in error.

As you may have noticed graphql send all the errors as status code 200. And the error I have returned from the API is under data.errors.

{
  "data": {
    "errors": [
      {
        "message": "Error: Token has expired",
        "locations": [
          {
            "line": 3,
            "column": 7
          }
        ],
        "path": [
          "createGame"
        ],
        "extensions": {
          "code": "403",
          "exception": {
            "stacktrace": [
              "Error: Error: Token has expired"
            ]
          }
        }
      }
    ],
    "data": {
      "createGame": null
    }
  },
  "status": 200,
  "statusText": "OK",
  "headers": {
    "content-type": "application/json; charset=utf-8"
  },
  "config": {
    "url": "http://localhost:4200/graphql",
    "method": "post",
    "data": "{\"query\":\"\\n    mutation {\\n      createGame (name: \\\"SA\\\", shortName: \\\"s\\\") {\\n        id,\\n        name,\\n        shortName\\n      }\\n    }\\n  \"}",
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/json",
      "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxLCJlbXBsb3llZUlkIjowLCJ1c2VyUm9sZUlkIjozLCJwYXNzd29yZCI6IiQyYiQxMCRwNTE2V1hnSGZXdWx6czVmY2o2ZGp1Q09lUzF0UUw3U2MySEIuMDRPUmpWekh6VnduSTNwNiIsImlzQWN0aXZlIjp0cnVlLCJjcmVhdGVkQXQiOiIyMDE5LTA4LTE5VDA5OjMxOjA5LjAzOVoiLCJ1cGRhdGVkQXQiOiIyMDE5LTA4LTE5VDA5OjMxOjA5LjA0MVoifSwiaWF0IjoxNTY3ODcyNTk2LCJleHAiOjE1Njc4NzI2MDZ9.HpNE9m5YEUv0qgBHxsEoQMd1p29TkOqvQzYF7ptljJ0"
    },
    "baseURL": "http://localhost:4200/graphql",
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1
  },
  "request": {}
}

The problem I am having is that I am integrating axios response intercetor in my Front-end

http.interceptors.response.use(
    /**
     * Leave response as it is.
     */
    (response: any) =>  response,
    /**
     * This interceptor checks if the response had a 401 status code, which means
     * that the access token used for the request has expired. It then refreshes
     * the access token and resends the original request.
     */
    unauthorizedResponseHandlerInterceptor
  );

And the unauthorizedResponseHandlerInterceptor function is only called by Axios when then there is an error but my graphql server is returning the status as 200 so the function does not get called.

Is there any way for me to modify the axios response interceptor so that it checks the value in data.errors instead of status

I am using graphql in my application and it sends the following response in error.

As you may have noticed graphql send all the errors as status code 200. And the error I have returned from the API is under data.errors.

{
  "data": {
    "errors": [
      {
        "message": "Error: Token has expired",
        "locations": [
          {
            "line": 3,
            "column": 7
          }
        ],
        "path": [
          "createGame"
        ],
        "extensions": {
          "code": "403",
          "exception": {
            "stacktrace": [
              "Error: Error: Token has expired"
            ]
          }
        }
      }
    ],
    "data": {
      "createGame": null
    }
  },
  "status": 200,
  "statusText": "OK",
  "headers": {
    "content-type": "application/json; charset=utf-8"
  },
  "config": {
    "url": "http://localhost:4200/graphql",
    "method": "post",
    "data": "{\"query\":\"\\n    mutation {\\n      createGame (name: \\\"SA\\\", shortName: \\\"s\\\") {\\n        id,\\n        name,\\n        shortName\\n      }\\n    }\\n  \"}",
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/json",
      "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxLCJlbXBsb3llZUlkIjowLCJ1c2VyUm9sZUlkIjozLCJwYXNzd29yZCI6IiQyYiQxMCRwNTE2V1hnSGZXdWx6czVmY2o2ZGp1Q09lUzF0UUw3U2MySEIuMDRPUmpWekh6VnduSTNwNiIsImlzQWN0aXZlIjp0cnVlLCJjcmVhdGVkQXQiOiIyMDE5LTA4LTE5VDA5OjMxOjA5LjAzOVoiLCJ1cGRhdGVkQXQiOiIyMDE5LTA4LTE5VDA5OjMxOjA5LjA0MVoifSwiaWF0IjoxNTY3ODcyNTk2LCJleHAiOjE1Njc4NzI2MDZ9.HpNE9m5YEUv0qgBHxsEoQMd1p29TkOqvQzYF7ptljJ0"
    },
    "baseURL": "http://localhost:4200/graphql",
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1
  },
  "request": {}
}

The problem I am having is that I am integrating axios response intercetor in my Front-end

http.interceptors.response.use(
    /**
     * Leave response as it is.
     */
    (response: any) =>  response,
    /**
     * This interceptor checks if the response had a 401 status code, which means
     * that the access token used for the request has expired. It then refreshes
     * the access token and resends the original request.
     */
    unauthorizedResponseHandlerInterceptor
  );

And the unauthorizedResponseHandlerInterceptor function is only called by Axios when then there is an error but my graphql server is returning the status as 200 so the function does not get called.

Is there any way for me to modify the axios response interceptor so that it checks the value in data.errors instead of status

Share Improve this question edited Sep 8, 2019 at 6:34 acdcjunior 136k37 gold badges338 silver badges310 bronze badges asked Sep 8, 2019 at 5:59 Sagar AcharyaSagar Acharya 1,8814 gold badges24 silver badges38 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

The first callback of the interceptor gets called when there is no error. You could do some custom check based on how your API sends errors:

http.interceptors.response.use(
    /**
     * Leave response as it is.
     */
    (response: any) => {
      if (response.data.errors) {
          let customError = new Error(response.data.errors[0].message);
          response.original_status = response.status
          response.status = response.data.errors[0].extensions.code
          customError.response = response;
          return Promise.reject(customError);
      }
      return response;
    },
    /**
     * This interceptor checks if the response had a 401 status code, which means
     * that the access token used for the request has expired. It then refreshes
     * the access token and resends the original request.
     */
    unauthorizedResponseHandlerInterceptor
  );

It is quite flexible. As shown above, you can even turn a successful call into an error, by returning Promise.reject() in the interceptor.

Here's a fiddle to play with: https://jsfiddle/acdcjunior/pvb1kj87/

axios.interceptors.response.use((response) => {
  if (response.data.errors) {
    let customError = new Error(response.data.errors[0].message);
    response.original_status = response.status
    response.status = response.data.errors[0].extensions.code
    // add some properties to make it look like a regular axios error
    customError.response = response;
    customError.request = response.request;
    customError.config = response.config;
    customError.isAxiosError = true; // or not

    return Promise.reject(customError);
  }
  return response;
}, (error) => {
  // Do something with response error
  return Promise.reject(error);
});

(async () => {

  console.log('*** regular axios error:')

  await axios.get(`https://example./DOESNOTEXIST`)
    .then((data) => {
      console.log('success -->', data)
    })
    .catch((e) => {
      console.log('error -->', e)
    })

  console.log('*\n*\n*')
  console.log('*** simulating error:')

  axios.get(`https://api.myjson./bins/d7hbp`)
    .then((data) => {
      console.log('success -->', data)
    })
    .catch((e) => {
      console.log('error -->', e)
    })

})();
<script src="https://unpkg./axios/dist/axios.min.js"></script>
Open dev tools and check the console!

本文标签: javascriptHow to have custom error code check for axios response interceptorStack Overflow