·
Across the Great Wall, we can reach every corner in the world.

抛,业务上最好包装一层 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 统一拦截,进行日志打印、安全审计、包装返回。