如何对 axios 响应拦截器进行自定义错误代码检查?

2024-04-06

我在我的应用程序中使用 graphql,它错误地发送以下响应。

您可能已经注意到 graphql 将所有错误作为状态代码 200 发送。我从 API 返回的错误位于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": {}
}

我遇到的问题是我正在前端集成 axios 响应拦截器

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该函数仅在出现错误时由 Axios 调用,但我的 graphql 服务器返回状态为 200,因此该函数不会被调用。

我有什么方法可以修改 axios 响应拦截器,以便它检查中的值数据错误代替status


当没有错误时,拦截器的第一个回调将被调用。您可以根据 API 发送错误的方式进行一些自定义检查:

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
  );

它非常灵活。如上所示,您甚至可以通过返回将成功的调用转变为错误Promise.reject()在拦截器中。

这是一个可以玩的小提琴:https://jsfiddle.net/acdcjunior/pvb1kj87/ https://jsfiddle.net/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.com/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.com/bins/d7hbp`)
    .then((data) => {
      console.log('success -->', data)
    })
    .catch((e) => {
      console.log('error -->', e)
    })

})();
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Open dev tools and check the console!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何对 axios 响应拦截器进行自定义错误代码检查? 的相关文章

  • 限制 Axios 请求

    我正在使用 axios 向 Deezer API 发出请求 不幸的是 使用 Deezer 的 API 当您请求艺术家的专辑时 它不包括专辑曲目 因此 我正在通过请求艺术家的专辑 然后对每个专辑执行后续的 axios 请求来解决这个问题 我遇
  • 循环遍历数组并删除项目,而不中断 for 循环

    我有以下 for 循环 当我使用splice 要删除一个项目 我发现 秒 未定义 我可以检查它是否未定义 但我觉得可能有一种更优雅的方法来做到这一点 我们的愿望是简单地删除一个项目并继续 for i 0 len Auction auctio
  • 如何检查是否存在可能的路径?

    我正在开发一个基于 javascript 的实验性游戏 玩家必须在二维平铺地图上移动才能退出 请随意检查这个小提琴并演奏 http jsfiddle net moonlife 74vLd 我只是随机放置障碍物 但有时障碍物会挡住玩家和出口之
  • 需要使用 iFrame API 隐藏 YouTube 品牌

    我正在使用 YouTube iFrame API 在我的自定义播放器 javascript 播放器 中加载视频 我需要隐藏 Youtube 品牌 但是在 iOS 设备上 它显示带有以下参数的徽标 playerVars fs 1 autopl
  • React中如何触发同级组件的函数?

    I am new to front end world and could not figure out how to trigger a function from a sibling component Lets say I have
  • Dialogflow Fulfillment Webhook 调用失败

    I am new to dialogflow fulfillment and I am trying to retrieve news from news API based on user questions I followed doc
  • 在自动完成上添加 jQuery 延迟

    我正在尝试为应用程序创建 jQuery 自动完成 search input on keyup function search this val autocomplete div autocomplete get ajax search se
  • 角度垫排序不适用于带点表示法的 matColumnDef

    我正在尝试按列对表进行排序 当我必须过滤另一个结果中的结果时 就会出现问题 我尝试通过括号表示法和点表示法访问该属性 但没有给出结果 还将最终节点放置在 matColumnDef 中 但失败 因为有 2 列同名 table table
  • 如何在 jQuery 中将标题转换为 URL slug?

    我正在 CodeIgniter 中开发一个应用程序 我试图在表单上创建一个字段来动态生成URL slug 我想做的是删除标点符号 将其转换为小写 然后用连字符替换空格 例如 Shane s Rib Shack 将变成 shanes rib
  • Node.js Express 4.0 中的 res.render 回调参数的用途是什么?

    目的是什么res render回调参数 在什么情况下 由于模板已被指定为第一个参数 因此人们会想要使用这样的回调参数 这是文档中的代码 send the rendered view to the client res render inde
  • fadeOut() 和slideUp() 同时进行?

    我已经发现jQuery 淡出然后滑动 https stackoverflow com questions 734554 jquery fadeout then slideup这很好 但不是那个 我怎么能够fadeOut and slideU
  • Javascript:我应该隐藏我的实现吗?

    作为一名 C 程序员 我有一个习惯 将可以而且应该私有的东西设为私有 当 JS 类型向我公开其所有私有部分时 我总是有一种奇怪的感觉 而且这种感觉并没有被 唤起 假设我有一个类型draw方法 内部调用drawBackground and d
  • 如何在具有相同值的下拉菜单上触发 jQuery 更改事件

    即使用户选择相同的值 如何每次都触发 jQuery 更改事件 我需要刷新效果 例如如果用户选择Lawyer它会发出警报hello然后用户再次选择Lawyer从下拉菜单中 它应该发出警报hello 我怎样才能实现它 以下是代码 jQuery
  • 如何按 Angular 表中的属性(该属性具有单个 rownspan)进行分组?

    我没有找到这个问题的合适标题 我的问题是 例如 我有一个包含两列的表 列汽车品牌和列汽车型号 我希望表是 like in this picture 换句话说 品牌名称只会出现 1 次 我的输入数组采用以下 json 格式 brand Aud
  • 如何根据另一个下拉列表中的选择动态填充下拉列表中的选项?

    我有一个表 其中包含类别信息 例如产品 我已将它们列在下拉菜单中 现在 我需要做的是 在下一个下拉菜单中列出所选类别的子类别 我希望 javascript 是必需的 但我对 javascript 还不太熟悉 将非常感谢您的帮助 你应该使用
  • 在 Android Chrome 中隐藏 HTML5 音频/视频通知

    我的网络应用程序上有一个 HTML5 音频元素 在某些时候 我使用以下代码以编程方式停止播放 audioElement pause audioElement currentTime 0 播放音频时 我的 Android 设备 使用 Goog
  • 标记(Markdown)+ Mermaid(流程图和图表)

    努力去争取 美人鱼 https github com knsv mermaid https github com knsv mermaid跟 共事 标记 https github com chjj marked https github c
  • Vue-Router 抽象父路由

    我正在尝试将当前网站迁移到 vuejs 站点地图必须是 login signup password reset browse search dozens of other routes 由于其中一些路线共享大量 fx 因此我将它们设为父路线
  • Jquery 以编程方式更改

    文本

    编辑 解决方案是将其添加到个人资料页面而不是性别页面 profile live pageinit function event p pTest text localStorage getItem gender 我在列表视图中有一个带有一些文
  • 如何通过点击复制 folium 地图上的标记位置?

    I am able to print the location of a given marker on the map using folium plugins MousePosition class GeoMap def update

随机推荐