全局异常未能正确捕获到对应的异常

自定义Validation验证器遇到的问题

抛出的异常没有能被指定的TaskValidException.class方法拦截到。故写这个原因

  • 全局异常拦截只能拦截相同的异常。只能通过解析转入自定义的异常。
  • 自定义的异常继承的异常要是一家子的。如TaskValidException和ValidationException。这样就能在全局捕获到后能够解析出来

全局异常中通过拦截ValidationException来捕获我想要的异常

java 复制代码
package com.tcmp.task.web.intercepter;

import com.tcmp.task.api.constants.ErrMsg;
import com.tcmp.task.api.domain.BaseResultEntity;
import com.tcmp.task.api.domain.FailResultEntity;
import com.tcmp.task.api.exception.TaskValidException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ValidationException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 异常处理
 *
 * @Author: zyy
 * @Date: Created on 9:36 2021/1/21.
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionInterceptor implements AsyncUncaughtExceptionHandler {
    /**
     * 校验异常
     *
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseBody
    public BaseResultEntity handleIllegalArgumentException(HttpServletRequest request, IllegalArgumentException e) {
        log.error("拦截到校验异常: {}, {}", request.getRequestURI(), e.getMessage(), e);
        return new FailResultEntity(e.getMessage());
    }

    /**
     * 校验异常
     *
     * @param request 当前 HTTP 请求
     * @param e 包装的异常
     * @return 异常处理结果
     */
    @ExceptionHandler({TaskValidException.class})
    @ResponseBody
    public BaseResultEntity handleTaskValidException(HttpServletRequest request, TaskValidException e) {
        log.error("拦截到校验异常: {}, {}", request.getRequestURI(), e.getMessage(), e);
        return new FailResultEntity(e.getErrorCode(), e.getErrorMessage());
    }


    /**
     * 处理 InvocationTargetException 异常。
     * InvocationTargetException 是在通过反射调用方法时抛出的异常,其实际原因可以通过 getCause() 方法获取。
     *
     * @param request 当前的 HttpServletRequest 对象,用于获取请求的详细信息。
     * @param e 抛出的 InvocationTargetException 异常。
     * @return BaseResultEntity 对象,包含具体的错误信息。
     *         如果实际原因是 TaskValidException,则调用 handleTaskValidException 方法进行处理。
     *         否则,返回一个包含系统通用错误信息的 FailResultEntity。
     */
    @ExceptionHandler(ValidationException.class)
    @ResponseBody
    public BaseResultEntity handleInvocationTargetException(HttpServletRequest request, ValidationException e) {
        Throwable cause = e.getCause();
        if (cause instanceof TaskValidException) {
            return handleTaskValidException(request, (TaskValidException) cause);
        }
        return new FailResultEntity(ErrMsg.SYS_ERROR);
    }


    /**
     * 处理业务异常
     *
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler({Exception.class})
    @ResponseBody
    public BaseResultEntity handleGenericException(HttpServletRequest request, Exception e) {
        log.error("拦截到通用异常: {}, {}", request.getRequestURI(), e.getMessage(), e);
        return new FailResultEntity(ErrMsg.SYS_ERROR);
    }

    @Override
    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
        log.error("异步方法执行异常: 方法名 - {}, 异常信息 - {}", method.getName(), ex.getMessage(), ex);
        // 可以在这里发送通知或者记录日志等操作
    }
}

定义的验证异常

java 复制代码
package com.tcmp.task.api.exception;

import com.tcmp.task.api.constants.ErrorCode;
import lombok.Data;

import javax.validation.ValidationException;


/**
 *  ucenter 异常
 *
 * @Author: zyy
 * @Date: Created on 13:36 2021/1/24.
 */
@Data
public class TaskValidException extends ValidationException {

    private Integer errorCode;

    private String errorMessage;

    public TaskValidException(String errorMessage) {
        super(errorMessage);
        this.errorMessage = errorMessage;
        this.errorCode = ErrorCode.FAIL;
    }

    public TaskValidException(Integer errorCode, String errorMessage) {
        super(errorMessage);
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }

}

自定义拦截验证器

java 复制代码
package com.tcmp.task.api.validation;

import com.tcmp.task.api.exception.TaskValidException;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import java.util.List;
public class NotEmptyTaskFieldValidator implements ConstraintValidator<NotEmptyTaskField, Object> {

    private String message;

    @Override
    public void initialize(NotEmptyTaskField constraintAnnotation) {
        this.message = constraintAnnotation.message();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            throw new TaskValidException(this.message);
        }
        if (value instanceof String) {
            if (((String) value).isEmpty()) {
                throw new TaskValidException(this.message);
            }
        }
        if (value instanceof List) {
            if (((List<?>) value).isEmpty()) {
                throw new TaskValidException(this.message);
            }
        }
        return true;
    }
}

自定义验证注解

java 复制代码
package com.tcmp.task.api.validation;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = NotEmptyTaskFieldValidator.class)
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotEmptyTaskField {
    String message() default "字段不能为空";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
相关推荐
noravinsc13 天前
django admin 添加自定义页面
django·自定义·admin
码农飞飞5 个月前
详解Rust宏编程
开发语言·算法·rust·自定义·使用场景·宏编程
宋冠巡5 个月前
Spring Boot Validation 封装自定义校验注解和校验器(validation-spring-boot-starter)
spring boot·参数校验·validation
Amd7946 个月前
Nuxt.js 应用中的 webpack:compile 事件钩子
webpack·自定义·编译·nuxt.js·构建·钩子·逻辑
初晴~6 个月前
【spring】参数校验Validation
java·c++·spring boot·后端·python·spring·validation
Amd7946 个月前
Nuxt.js 应用中的 webpack:configResolved事件钩子
webpack·自定义·开发·配置·nuxt.js·构建·钩子
Amd7946 个月前
Nuxt.js 应用中的 vite:compiled 事件钩子
自定义·vite·编译·nuxt·热更新·性能·钩子
Amd7946 个月前
Nuxt.js 应用中的 schema:resolved 事件钩子详解
json·自定义·vite·配置·nuxt·schema·钩子
Amd7946 个月前
Nuxt.js 应用中的 vite:extendConfig 事件钩子详解
自定义·开发·vite·配置·nuxt·构建·钩子