想问下各位后端错误处理怎么做比较优雅?

看了一些大厂的接口,不少都是直接 200 返回的,然后带个错误码。业务逻辑上是直接 service 层包装一下直接返回还是直接抛 Exception 的好?

backend
250 views
Comments
登录后评论
Sign In
·

只要你们团队方便,随心就行

·

我是直接抛 RuntimeException,让异常直接打断事务,然后 controllerAdvice 统一处理异常,包装返回。

·

如果直接返回,有时候事务执行到一半,就有脏数据,这种 bug 很危险,后期把数据整回来很麻烦。

·

抛 Exception吧

Exceptions should be thrown when the contract between a method and its caller cannot be fulfilled. This is the usage identified in the Java™ Language Specification.

抛出异常不是严格禁止的事情,如果在项目结构中需要处理“函数分内的事情”则不需要抛出异常如果是“分外”的事情,则需要抛出异常。

·

抛,业务上最好包装一层 exception 再 throw,可以参考 google api 的 grpc 异常接口,自己实现一个 rest 的版本。写法很简洁清晰,给个例子:

public Comment getById(Long commentId) {
    var comments = getByIds(List.of(commentId));
    if (comments.isEmpty()) {
        throw Status.NOT_FOUND.asRuntimeException();
    }
    return comments.get(0);
}

如果需要定义具体错误类型,使用一个 enum 定义:

public enum ErrorReason {
    COMMENT_DELETED,
    COMMENT_BLOCKED
}

这样用:

public Comment doSomething() {
    //... other code
    if (comment.getBlocked()) {
        var details = Details.newInstance().newErrorInfoBuilder()
                .domain("comment")
                .reason(ErrorReason.COMMENT_BLOCKED)
                .build();
        throw Status.FAILED_PRECONDITION.asRuntimeException(details);
    }
    return comment;
}

controllerAdvice 统一拦截,进行日志打印、安全审计、包装返回。

·

可以参考 google 的 api 规范:API design error,黑客说的错误处理就是这套实现。

·

RuntimeException+1

·

框架上把异常处理好,业务代码抛就行了,错误信息最好自己处理一下,尽量别在前端看到堆栈信息