分类
开发规范 技术

RESTFul API 错误处理规范

前言

错误处理是 Web 开发中普遍又重要的一个环节,是指前端通过 RESTFul 风格的 API 调用后端服务,而在 API 执行时,可能产生种种错误,包括参数不正确、代码逻辑错误或者第三方服务不可用。当错误发生时,需要前后端共同协作,处理好善后工作。本文旨在设计一套简洁实用的错误处理机制以指导前后端进行开发。涉及到错误的产生、转换、编码、显示、定位等多个方面,在设计过程中,主要考虑了以下问题:

  1. 应用程序错误、第三方库、服务产生的错误都应被妥善处理,不可遗漏
  2. 兼容 HTTP 规范
  3. 对程序和用户都保持友好
  4. 完整但简单
  5. 优雅的编码方式
  6. 便于定位问题

总则

客户端收到服务端返回的 HTTP response,需要关注两个地方:status code 和 body。若 status code 等于 200,表示这个请求被成功执行,body 中承载了预期的数据,客户端按照特定的业务逻辑处理即可。除此之外的所有 status code 皆表示发生了某种异常,此时 response 的 body 中会包含 json 格式的 code(Int) 和 message(String) 字段,用来指示错误的详细情况。

message 是对错误的描述,可能为空字符串,该描述一般来自于第三方库或开发者抛出异常时指定的 message,这个消息是给程序员看的,只作为前后端定位问题的工具,不应将其暴露给用户。

code 指示了错误的类型,前后端需要对每一个 code 代表的意义达成共识,当错误发生时,前端需要将该 code 转换为合适的消息显示给用户。通常情况下 code 的值为 0,表示无法提供具体的错误消息或者可以从 status code 以及上下文推断出来,或者发生了系统级别的错误,无法为用户展现有意义的消息。只有当错误是逻辑层面的并且可由用户主动避免,提供 code 才是有意义的。

以下列出了除 200 以外所有可能出现的 status code 以及相关的 code、message 的可能取值:

Status一般诱因CodeMessage
400客户端提供的参数不正确(一般由 spring 抛出异常),或逻辑不正确(由开发者抛出异常)>=0对错误的描述
401匿名用户访问了需要认证的资源,一般由 spring security 抛出0由框架提供
403访问了未授权的资源,一般由 spring security 抛出,或开发者抛出相关异常0由框架或开发者提供,需要注意安全类错误不得提供详细信息
404由框架(如接口未找到)或开发者(如ID指定的资源不存在)抛出0可能有值,指示不存在资源的类型
500服务端逻辑错误、第三方服务错误导致的未捕获异常0异常的 message

后端规范

  • 使用异常作为错误处理的主要手段,不要在编码中使用错误码、枚举等技术
  • 不需要包装框架或第三方抛出的异常,仅在必要的条件下这么做,所有的异常都应一视同仁,并确保最终得到处理
  • 充分利用框架或系统提供的异常,以减少自定义异常的数量
  • 为每个 HTTP 请求随机唯一的 Id,关联在日志中,并附带在对应 HTTP 相应的 X-Request-Id 头部。此外,如果请求中包含了 X-Request-Id 头,则应使用该 Id。该机制保证错误能被快速地定位到
  • 发生异常时,应在日志中详细记录,尤其是未捕获异常以及怀疑遭受安全攻击时

前端规范

  • 对用户输入参数做充分校验
  • 妥善处理异常状况,根据 status、code 以及上下文为用户提供友好的提示
  • 提示错误时,应同时显示 X-Request-Id,这样可以利用用户提供的报错截图快速定位问题

“RESTFul API 错误处理规范”上的一条回复