API的设计(1) - 错误处理

API的错误处理

正常结果 Response

当我们在定义一个函数接口的时候,往往会定义:

  • 接口名
  • 输入参数 Reqest
  • 返回结果 Response

以java为例,登陆接口定义会是类似:

User login(String username, String password);

异常结果 BizError

上述的接口定义,其实是不妥的,因为它定义了所谓的Happy Path 主流程需要的正常结果 Response;却没有定义Sad Path 分支流程所需要的异常结果 Biz Error

需要注意的是:主流程分支流程都属于业务逻辑的一部分,给与分支流程足够的重视,是软件成熟度提升的表现。

登陆是完全可能出现分支流程的,比方说,用户名/密码错误,账号被屏蔽等等;一个连密码错误处理不了的登陆程序,是非常糟糕的程序。

所以,API的定义可以调整为:

User login(String username, String pass) throw InvalidLoginException, AccountBannedException;

当然,我们也可以把InvalidLoginExceptionAccountBannedException都归为LoginError,然后使用Enum枚举属性来区分,那么接口会变成:

enum ErrorTypes {
  InvalidLogin = 1;
  AccountBanned = 2;
}

Class LoginError {
  ErrorTypes Error;
}

User login(String username, String pass) throw LoginError;

常见异常 CommonError

但这依旧不够,我们实现接口的时候,往往会使用一些框架、中间件,而它们自身又经常带有一些内置的常见异常 CommonError,比方说:

  • APIKeyNotProvided
  • InvalidParameter

等等,同样的,我们也可以把上述归类为CommonError,那么API定义会变成:

enum ErrorTypes {
  InvalidLogin = 1;
  AccountBanned = 2;
}

Class LoginException {
  ErrorTypes Error;
}

Class FrameworkException {
  ....
}

User login(String username, String password) throw LoginError, CommonError;

CommonErrorBizError的区别在于后者是针对单一API的,而前者则可能会存在于大部分,甚至所有API。

BizError是由对当前的API提供方的业务代码返回,需要调用方针对返回的BizError进行处理,然后进入当前业务的分支流程,这样的流程是需要我们根据业务进行特定编码;它是与业务逻辑代码强相关的。

CommonError被返回时,则可能是跟具体业务无关,它一般是由API提供方使用的框架、中间件直接返回的,调用方收到CommonError时,可能不会进入业务的分支流程,而是进行一些同样的处理,比方说,提示用户登录后操作,或者重新输入。

它需要被底层绑定的通用代码,而不是当前的业务代码处理。

错误 Error

程序运行的时候,是可能遇到比异常更加严重的Error,比方说:TimeOutErrorOutOfMemeryError,甚至SegmentFaultError等等。

API遇到错误的时候,无论是提供方还是调用方,几乎都无法进行任何具体处理,最多由通用代码打一下日志,然后提示一下用户稍后重试。

我们只有把:

  • 正常结果
  • 异常结果
  • 常见异常
  • 错误

一个成熟的API,需要对这四种四者都考虑进去。

总结

正常结果 异常结果 常见异常 错误
业务 强相关 强相关 弱相关 无关
返回者 业务代码 业务代码 框架/中间层 其它
处理者 业务代码 业务代码 通用代码 通用代码
Response BizError CommonError Error
Business Relation Strong Strong Weak N.A.
Returner Biz Code Biz Code Framework/Middleware Others
Handler Biz Code Biz Code General Code General Code

下一节,我会推荐一种通用的API框架/风格 - protoapi,鼓励按正常结果异常结果常见异常错误这四种划分来定义我们的API。

你可能感兴趣的:(API的设计(1) - 错误处理)