全局异常处理器

news/2024/9/30 1:28:25

项目中的全局异常是如何处理的?

全局异常处理逻辑

一般项目开发有两种异常:

  • 预期异常(程序员手动抛出)

  • 运行时异常

img

在目前的项目中已经提供了全局异常处理器

img

  • BaseException 基础异常,如果业务中需要手动抛出异常,则需要抛出该异常

package com.zzyl.exception;


import com.zzyl.enums.BasicEnum;
import lombok.Getter;
import lombok.Setter;

/**
* BaseException
* @author itheima
**/
@Getter
@Setter
public class BaseException extends RuntimeException {

   private BasicEnum basicEnum;

   public BaseException(BasicEnum basicEnum) {
       this.basicEnum = basicEnum;
  }
}

其中BaseException中的参数为一个枚举,可以在BasicEnum自定义业务中涉及到的异常

package com.zzyl.enums;

import com.zzyl.base.IBasicEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* 基础枚举
*
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum BasicEnum implements IBasicEnum {

   SUCCEED(200, "操作成功"),
   SECURITY_ACCESSDENIED_FAIL(401, "权限不足!"),
   LOGIN_FAIL(401, "用户登录失败"),
   LOGIN_LOSE_EFFICACY(401, "登录状态失效,请重新登录"),
   SYSYTEM_FAIL(500, "系统运行异常"),


   //权限相关异常:1400-1499
   DEPT_DEPTH_UPPER_LIMIT(1400, "部门最多4级"),
   PARENT_DEPT_DISABLE(1401, "父级部门为禁用状态,不允许启用"),
   DEPT_NULL_EXCEPTION(1402, "部门不能为空"),
   POSITION_DISTRIBUTED(1403, "职位已分配,不允许禁用"),
   MENU_NAME_DUPLICATE_EXCEPTION(1404, "菜单路由重复"),
 


   //业务相关异常:1500-1599
   WEBSOCKET_PUSH_MSG_ERROR(1500, "websocket推送消息失败"),
   CLOSE_BALANCE_ERROR(1501, "关闭余额账户失败"),
   MONTH_BILL_DUPLICATE_EXCEPTION(1502, "该老人的月度账单已生成,不可重复生成"),
   MONTH_OUT_CHECKIN_TERM(1503, "该月不在费用期限内");

   /**
    * 编码
    */
   public final int code;
   /**
    * 信息
    */
   public final String msg;
}
  • GlobalExceptionHandler 全局异常处理器

package com.zzyl.exception;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zzyl.base.ResponseResult;
import com.zzyl.enums.BasicEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.io.FileNotFoundException;
import java.nio.file.AccessDeniedException;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

   /**
    * 处理自定义异常BaseException。
    * 返回自定义异常中的错误代码和错误消息。
    *
    * @param exception 自定义异常
    * @return 响应数据,包含错误代码和错误消息
    */
   @ExceptionHandler(BaseException.class)
   public ResponseResult<Object> handleBaseException(BaseException exception) {
       exception.printStackTrace();
       if (ObjectUtil.isNotEmpty(exception.getBasicEnum())) {
           log.error("自定义异常处理:{}", exception.getBasicEnum().getMsg());
      }

       return ResponseResult.error(exception.getBasicEnum());

  }

   /**
    * 处理其他未知异常。
    * 返回HTTP响应状态码500,包含错误代码和异常堆栈信息。
    *
    * @param exception 未知异常
    * @return 响应数据,包含错误代码和异常堆栈信息
    */
   @ExceptionHandler(Exception.class)
   public ResponseResult<Object> handleUnknownException(Exception exception) {
       exception.printStackTrace();
       if (ObjectUtil.isNotEmpty(exception.getCause())) {
           log.error("其他未知异常:{}", exception.getMessage());
      }
       return ResponseResult.error(500,exception.getMessage());
  }

}

项目中集成

程序员手动抛出业务异常

当床位新增失败的时候,可以直接抛出BaseException

@Override
public void addBed(BedDto bedDto) {
   Bed bed = BeanUtil.toBean(bedDto, Bed.class);
   bed.setCreateTime(LocalDateTime.now());
   bed.setCreateBy(1L);
   bed.setBedStatus(0);
   try {
       bedMapper.addBed(bed);
  } catch (Exception e) {
       throw new BaseException(BasicEnum.BED_INSERT_FAIL);
  }
}

测试:

当重复录入床位编号的时候,则会抛出:床位新增失败,而此时的执行逻辑就是走了全局异常处理器

不可知异常处理

比如,在文件上传的接口中,如果上传文件失败,则可以抛出RuntimeException异常,由于RuntimeException异常不是自定义异常,一旦触发就是走全局异常处理器的未知异常

/**
* 文件上传
*
* @param file 文件
* @return 上传结果
* @throws Exception 异常
*/
@PostMapping("/upload")
@ApiOperation("文件上传")
public ResponseResult<String> upload(
       @ApiParam(value = "上传的文件", required = true)
       @RequestPart("file") MultipartFile file) throws Exception {

   // 校验是否为图片文件
   try {
       BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
  } catch (Exception e) {
       throw new RuntimeException("上传图片失败");
  }

   if (file.getSize() == 0) {
       throw new RuntimeException("上传图片不能为空");
  }

   // 获得原始文件名
   String originalFilename = file.getOriginalFilename();
   // 获得文件扩展名
   String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
   String fileName = UUID.randomUUID().toString() + extension;

   String filePath = fileStorageService.store(fileName, file.getInputStream());

   return ResponseResult.success(filePath);
}

结论:

  • 一旦文件上传失败,则会走全局异常处理器的未知异常

  • 如果系统抛出了其他异常,非BaseException,都会走未知异常

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/29946.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

T2,3,4,5,9动态背包问题

本文主要介绍常见的四种背包问题前言 本文主要介绍常见的四种背包问题,思维导图如下:一、01背包💡 现有 N 件物品和一个最多能承重 M 的背包,第 i 件物品的重量是 wi​,价值是 vi​。在背包能承受的范围内,试问将哪些物品装入背包后可使总价值最大,求这个最大价值。因为…

luogu P4342[IOI1998]Polygon

题目大意 给定一个多边形,对应节点上标记有一个数字,每条边上标记有加(t)或乘(x)表示相邻两个节点可进行的操作,操作后两个节点将合并为一个节点,首先删去一条边(不进行操作),之后在若干次操作后使得该多边形只剩一个节点,且要求所剩节点标记的数最大化,询问最大的…

ES底层原理

1、倒排索引 Elasticsearch 使用一种称为倒排索引的结构,它适用于快速的全文搜索。 有倒排索引,肯定会对应有正向索引:正向索引(forward index) 反向索引(inverted index,实际就是倒排索引)所谓的正向索引,就是搜索引擎会将待搜索的文件都对应一个文件ID,搜索时将这个…

金蝶Kis云代码实现

1、金蝶认证(获取到token)也就是code,获取业务接口网关和auth_data,请求头 RequestHeader类 package com.api.xic.jd.tool; import net.sf.json.JSONObject; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import…

qt实现窗口B始终显示在窗口A上,且上层窗口在电脑任务栏不显示缩图

场景:窗口A上面始终显示窗口B(透明背景) /*****************************************/ 首先,在主窗口即底部窗口重写changeEvent QtGuiApplication1::QtGuiApplication1(QWidget *parent) : QWidget(parent) , m_pQtGuiClass(nullptr) {ui.setupUi(this);setWindowFlags(Q…

微信开发者工具请求接口 Provisional headers are shown

前情最近全权负责公司小程序项目的开发,使用的uniapp技术栈。 坑在和服务端联调的时候发现,接口pending很久,而且时不时的报Provisional headers are shown,而且出现的概率很大方法尝试?有可能是浏览器插件拦截了,把有可能推荐的插件全停了也没有用 有可能是防火墙拦截了…

时序图

时序图时序图1. 参考资料 2. 基础 3. 符号3.1. 斜线形式的上升沿、下降沿 3.2. Either or 信号 3.3. 波形省略3.2.1. 虚线 3.2.2. 波浪号3.4. 地址&数据表示4. 实例-WT588F语音芯片时序图4.1. 了解背景 4.2. 分析 4.3. 列逻辑 4.4. 根据逻辑写代码(伪代码)5. 总结 others…