美文网首页
[Java] 如果优雅的处理业务异常

[Java] 如果优雅的处理业务异常

作者: zqq90 | 来源:发表于2019-06-10 18:57 被阅读0次

注: 限于篇幅问题,省略了一些代码实现、文档、一些次要的方法、以及一些衍生方法

背景

https://gitee.com/oschina/bullshit-codes/blob/master/java/BadException.java

  • 异常不能复用!异常不能复用!异常不能复用!
  • 其他问题都是毛毛雨啦

少说废话,看代码

  • 先有个统一的响应体
@lombok.Data
@RequiredArgsConstructor(staticName = "of")
@SuppressWarnings({"WeakerAccess", "unused"})
public class ResultBody<T> {

    @JsonIgnore
    private final int httpStatusHint;
    private final boolean success;
    private final String code;
    private final String message;
    private final T data;

    public static <T> ResultBody<T> success() { ... }

    public static <T> ResultBody<T> success(T data) { ... }

    public static <T> ResultBody<T> failed(String code, String message) { ... }

   // 其他的 success(...) failed(...) 略 ...

    @JsonIgnore
    public boolean isFailed() {
        return !isSuccess();
    }
}
  • 再有个统一的业务异常类
@lombok.Getter
@SuppressWarnings({"WeakerAccess", "unused"})
public class BusinessException extends RuntimeException {

    protected final int statusHint;
    protected final String code;

    public BusinessException(String code, String message)  { ... }

    public BusinessException(int statusHint, String code, String message) { ... }

    public BusinessException(String code, String message, Throwable cause) { ... }

    public BusinessException(int statusHint, String code, String message, Throwable cause) {
        //  需要的可以考虑关闭 writableStackTrace 提高性能
        super(message, cause, true, true);
        this.statusHint = statusHint;
        this.code = code;
    }

    public <T> ResultBody<T> toResultBody() {
        return ResultBody.failed(statusHint, code, getMessage());
    }

   // 其他方法略 ...
}
  • 接下来, 关键点!
@SuppressWarnings({"unused"})
public interface IErrors {

    // 为啥不是 `getName` 而是 `name` ? 别着急, 往后看
    String name();

    int getStatusHint();

    default String format(String code, Object[] args) {
        // Tip: 这里还可以处理国际化问题, 喜欢的话, 还可以用其他的占位符语法
        return MessageFormat.format(code, args);
    }

    default <T> ResultBody<T> result(String pattern, Object... args) {
        return ResultBody.failed(getStatusHint(), name(), format(pattern, args));
    }

    default BusinessException exception(String pattern, Object... args) {
        return new BusinessException(getStatusHint(), name(), format(pattern, args));
    }

    default void whenNull(Object obj, String pattern, Object... args) {
        if (obj == null) {
            throw exception(pattern, args);
        }
    }

    default void whenFalse(boolean expr, String pattern, Object... args) {
        if (!expr) {
            throw exception(pattern, args);
        }
    }

    // 其他 whenXxx(...) 方法略
}
  • 之后,随便定一个枚举,继承 IErrors 就可以了
@Getter
@RequiredArgsConstructor
public enum Errors implements IErrors {

    BAD_REQUEST(400),
    UNAUTHORIZED(401),
    NOT_FOUND(404),
    ILLEGAL_ARG(400),
    NOT_SUPPORTED(500),
    SYSTEM(500);

    private final int statusHint;
}

是的,Errors 是个枚举类,我们用枚举的 name 当做 Error Code 再合适不过了

  • 舒服了, 舒服了!
// 我们可以直接返回 ResultBody<T> 实例
return Errors.ILLEGAL_ARG
        .result("非法的参数:{0} = '{1}'", "name", name);

// 可以使用异常
if(bean == null){
    throw Errors.NOT_FOUND
            .exception("您所请求的资源不存在:id={0}", id);
}

// 还有更舒服的
Errors.NOT_FOUND
        .whenNull(bean, "您所请求的资源不存在:id={0}", id);
Errors.BAD_REQUEST
        .whenFalse(bean.isEnable(), "无法完成您的请求,因为该资源已被禁用:id={0}", id);
  • 当然,如果就这么完了,你肯定会质疑 IErrors 这个接口的必要性,请看:
// 像这样,每个模块都可以有自己的 Errors
@Getter
@RequiredArgsConstructor
public enum MyErrors implements IErrors {

    // 当然是根据自己的业务来定义啦
    PASSWORD_EXPIRED(400),
    ACCOUNT_DISABLED(400),
    INVALID_TOKEN(401);

    private final int statusHint;
}

是不是很方便?!

如果有任何意见或建议, 欢迎在评论区留言。”

相关文章

  • [Java] 如果优雅的处理业务异常

    注: 限于篇幅问题,省略了一些代码实现、文档、一些次要的方法、以及一些衍生方法 背景 https://gitee....

  • Exception

    Java 中 9 个处理 Exception 的最佳实践 Java 中的异常和处理详解 如何优雅的设计 Java ...

  • springboot 构建统一异常&统一返回

    如何优雅的处理异常,并将异常优雅的封装到返回中进行统一返回?如果让我们专注于业务代码的书写呢,这篇就够了,加油。一...

  • Java优雅的异常处理

    Java中出现报异常,会导致代码无法成功编译,影响后面代码的执行,所以我们要解决这些异常。 常用的异常的处理方式有...

  • 我抛了几个异常,领导却说我代码写得好

    前言 小时候写Java代码碰见异常要么全抛,要么全捕。没有优雅的处理过异常,自然也就谈不上利用Java优秀的异常处...

  • 优雅处理你的Java异常

    作者:叶知泉 来源:https://my.oschina.net/c5ms/blog/1827907 本文介绍 本...

  • 怎么优雅的处理Java异常?

    0 本文介绍 本文仅按照业务系统开发角度描述异常的一些处理看法.不涉及java的异常基础知识,可以自行查阅《Jav...

  • 如何优雅的处理异常(java)?

    Java中异常提供了一种识别及响应错误情况的一致性机制,有效地异常处理能使程序更加健壮、易于调试。异常之所以是一种...

  • java优雅的进行异常处理

    一、定义一个异常的枚举类 二、定义一个异常的结果集 三、 自定义一个异常,继承RunTimeException,里...

  • Java-优雅的异常处理

    异常处理 1.异常的概念及异常体系 1.什么是Java中的异常 1. 代码正常运行不会出问题,但是遇到意外,参数变...

网友评论

      本文标题:[Java] 如果优雅的处理业务异常

      本文链接:https://www.haomeiwen.com/subject/bcjtfctx.html