专栏首页猿天地Kitty Cloud(HTTP/RPC)的全局异常处理

Kitty Cloud(HTTP/RPC)的全局异常处理

项目地址

https://github.com/yinjihuan/kitty-cloud[1]

异常处理不用我讲,大家都清楚。单独的异常处理太繁琐,全局异常处理可以在一个应用中统一进行异常的处理,非常方便。目前全局异常处理用的也越来越广泛,今天跟大家来聊一聊 Kitty Cloud 中的全局异常是如何处理的?

为什么要使用全局异常处理呢?

使用全局异常处理后,我们不需要定义固定类型的返回值,当业务代码报错的时候直接通过异常处理方式来返回给前端或者 API 调用方错误信息。

不使用全局异常处理案例

Web 层

比如我们定义了一个 ResponseData 用来返回固定格式的数据,正常情况下不会有问题,给前端返回的格式也是固定的,如下:

{
  "code":200,
  "data":{
    "name":"yinjihuan"
  },
  "message":"success",
}

如果业务发生异常,那么这个接口就不会返回上面那样固定格式的数据了,会给我们返回错误页面。除了代码异常还有一种情况就是当访问的 Uri 错误的时候,也会给调用方返回 404 的错误页面,如下:

如果是传统的 Web 项目,里面包含了页面这是没问题的,我们也可以自定义错误页面让用户体验更好一点。但是在这个基本上是前后端分离的开发模式下,后端只提供的数据的 API,不会有页面的内容。所以就算出错了,就算使用者调用的 API 路径错了,也应该返回固定的格式,并且告诉调用方路径错了。所以我们需要全局的异常处理。

业务层

在业务层最常见的用法就是我们可以直接抛出自定义异常,这样在全局异常处理后给调用方返回的还是固定的格式,如果没有全局异常处理,我们可能会用固定的 Response 来做这件事,比如下面的代码:

public Response createOrder(CreateOrderParam param) {
    Response checkResponse = paramsCheck(param);
    if (!checkResponse.isSuccess()) {
       return checkResponse();
    }
    ...........
}
private Response paramsCheck(CreateOrderParam param) {
     if (param.getTotalPrice() <= 0){
        return Response.fail("金额错误");
     }

     if (param.getGoodsCount() <= 0){
        return Response.fail("数量错误");
     }
     return Response.success();
}

当我们有了全局异常处理后,这边就直接可以抛出自定义的异常了,代码看起来会简洁一些。

public Response createOrder(CreateOrderParam param) {
    paramsCheck(param);
    ...........
}
private void paramsCheck(CreateOrderParam param) {
     if (param.getTotalPrice() <= 0){
        throw new BizException(
           ResponseCode.PARAM_ERROR_CODE, "金额错误");
     }

     if (param.getGoodsCount() <= 0){
        throw new BizException(
           ResponseCode.PARAM_ERROR_CODE, "数量错误")
     }
}

业务层的异常跑出去后,在全局异常中会进行处理成固定的格式,然后返回给调用方。像很多开放平台的 API 都会有很多的 code 来表示不同的异常类型。

内部服务层

内部服务层也就是说内部服务之间的调用,比如我们用 Dubbo, 如果被调用的服务中没有进行全局异常处理,那么当调用的某个接口报错的时候,调用者这边就会直接报错。

如果我们想就算报错了,调用方这边还是能够获取到正常的响应内容,只不过是内容中会告诉我这个请求是成功的还是失败的。

比如下面的远程调用,如果有全局异常处理,那么就可以根据响应判断是否成功,如果没有的话就直接报错了,如果需要对错误进行处理,还得捕获异常进行处理。

ResponseData<UserResponse> user =
                        userRemoteService.getUser(userId);
if(user.isSuccess()) {
  .......
}

全局异常处理

Http 全局异常处理

关于 Http 的全局异常处理,这边就不细讲了,大家可以查看我的这篇文章:《最佳实践 - API 错误处理》https://mp.weixin.qq.com/s/sIkrZTzGP4caKHzKYKqT7A

处理后如果有报错,那么返回的也是固定的数据格式:

{
  code: 500,
  message: "/ by zero",
  data: null,
  domain: "kitty-cloud-article-provider",
  errors: null,
  requestId: "52a9f30323e80d82",
  success: false
}

Rpc(Dubbo)全局异常处理

Dubbo 的全局异常处理可以通过 Filter 进行处理,获取执行的结果去进行处理,如果有异常信息就将相应的内容改成统一的失败格式进行返回。

需要注意的是要将 Result 中的 Exception 设置为 null, 因为 Dubbo 内部的 org.apache.dubbo.rpc.filter.ExceptionFilter 也会对异常进行处理,移除掉后 ExceptionFilter 就不会执行对应的逻辑了。

Dubbo 处理后的效果也是会返回固定格式,如下:

参考资料

[1]

kitty-cloud: https://github.com/yinjihuan/kitty-cloud

相关推荐

本文分享自微信公众号 - 猿天地(cxytiandi),作者:尹吉欢

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 不要小看小小的 emoji 表情

    这篇文章得从一个 emoji 表情开始,我之前开源的一个 IM 项目中有朋友提到希望可以支持 emoji 表情传输。

    猿天地
  • Kitty-Cloud中的编码规范

    https://github.com/yinjihuan/kitty-cloud[1]

    猿天地
  • 从摩拜总是出现服务故障谈谈技术这件小事

    最近几天不知道怎么了,摩拜单车总是出现故障。 不是扫不了码就是关闭自行车时,车已经锁了,但是app上显示的还是使用中,也就是在关闭锁的一瞬间刚刚好服务器出问题了...

    猿天地
  • Mysql基础篇--面试优化数据库对象和使用技巧

    可以利用order by 子句完成随机抽取某些行的功能,他的原理就是order by rand()能够数据随机排序。

    小土豆Yuki
  • Ubuntu18.04下给Jupyter-NoteBook设置默认工作路径

    生成配置文件:jupyter-notebook --generate-config

    逸鹏
  • 关于网站图标favicon.ico那点事儿,你造吗?

    众所周知,联盟成员导航是中国博客联盟的特色之一。而网站图标则是导航的装饰之一,起到锦上添花的作用,让页面更精美耐看。 但是随着成员数量的增长,图标便成了页面的拖...

    张戈
  • nmap扫描主机存活情况 原

    –min-hostgroup 1024(调整并行扫描组的大小,最小分组设置为1024)

    青木
  • 【深度学习】自动驾驶:使用深度学习预测汽车的转向角度

    近年来,特别是在10年前Darpa挑战赛成功之后,全自动驾驶汽车的开发速度大大加快。自动驾驶汽车由许多部件组成,其中最关键的部件是驱动它的传感器和人工智能软件。...

    AiTechYun
  • WEB布局基础知识点图解

    用户1730674
  • E4A易安卓如何安装elb和文件夹类库

    前面爱游分享了一个E4A的类库合集(易安卓e4a类库合集),然后可能有些人不会使用,一直有人加爱游的微信问如何使用,今天爱游就来说说如何使用这些类库。

    爱游博客

扫码关注云+社区

领取腾讯云代金券