马丁短链02异常码 异常拦截器

news2024/11/25 2:31:37

全局统一返回实体

目的是除了数据信息,还要带上一些错误状态码,成功与否,错误信息等等以帮助更好理解可能的错误。

规约:默认的约定

异常码设计原则

A客户端异常 B服务端异常 C远程调用异常

具体异常码设计架构

然后用枚举实现这个IErrorCode,在枚举常量中放入所有既定异常码和信息。

/**
 * 基础错误码定义
 */
public enum BaseErrorCode implements IErrorCode {

    // ========== 一级宏观错误码 客户端错误 ==========
    CLIENT_ERROR("A000001", "用户端错误"),

    // ========== 二级宏观错误码 用户注册错误 ==========
    USER_REGISTER_ERROR("A000100", "用户注册错误"),
    USER_NAME_VERIFY_ERROR("A000110", "用户名校验失败"),
    USER_NAME_EXIST_ERROR("A000111", "用户名已存在"),
    USER_NAME_SENSITIVE_ERROR("A000112", "用户名包含敏感词"),
    USER_NAME_SPECIAL_CHARACTER_ERROR("A000113", "用户名包含特殊字符"),
    PASSWORD_VERIFY_ERROR("A000120", "密码校验失败"),
    PASSWORD_SHORT_ERROR("A000121", "密码长度不够"),
    PHONE_VERIFY_ERROR("A000151", "手机格式校验失败"),

    // ========== 二级宏观错误码 系统请求缺少幂等Token ==========
    IDEMPOTENT_TOKEN_NULL_ERROR("A000200", "幂等Token为空"),
    IDEMPOTENT_TOKEN_DELETE_ERROR("A000201", "幂等Token已被使用或失效"),

    // ========== 一级宏观错误码 系统执行出错 ==========
    SERVICE_ERROR("B000001", "系统执行出错"),
    // ========== 二级宏观错误码 系统执行超时 ==========
    SERVICE_TIMEOUT_ERROR("B000100", "系统执行超时"),

    // ========== 一级宏观错误码 调用第三方服务出错 ==========
    REMOTE_ERROR("C000001", "调用第三方服务出错");

    private final String code;

    private final String message;

    BaseErrorCode(String code, String message) {
        this.code = code;
        this.message = message;
    }

    @Override
    public String code() {
        return code;
    }

    @Override
    public String message() {
        return message;
    }
}

全局异常拦截器:

对所有的controller,处理一些未经捕获的异常,做一些特定处理

它的意义在于:比如你捕获了一个runtime exception,但是你并不知道具体是什么错误,也就不知道要用哪一个具体的异常码(上面设计的),所以这里自定义详细异常以对应不同的异常码,这样拦截器捕获什么自定义异常就返回什么对应异常码。

自定义一个抽象全局异常,然后三大类异常(分别对应三类异常码)继承抽象异常

示例:客户端异常,,构造是1.只自定义一个错误码 2.可以自定义信息 + 默认一级宏观客户端错误码 3.  自定义信息 + 具体客户端错误码  4.什么都要

service里抛异常

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.nageoffer.shortlink.admin.common.convention.errorcode.BaseErrorCode;
import com.nageoffer.shortlink.admin.common.convention.exception.AbstractException;
import com.nageoffer.shortlink.admin.common.convention.result.Result;
import com.nageoffer.shortlink.admin.common.convention.result.Results;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Optional;

/**
 * 全局异常处理器
 *
 */
@Component
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 拦截参数验证异常
     */
    @SneakyThrows
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        FieldError firstFieldError = CollectionUtil.getFirst(bindingResult.getFieldErrors());
        String exceptionStr = Optional.ofNullable(firstFieldError)
                .map(FieldError::getDefaultMessage)
                .orElse(StrUtil.EMPTY);
        log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionStr);
        return Results.failure(BaseErrorCode.CLIENT_ERROR.code(), exceptionStr);
    }

    /**
     * 拦截应用内抛出的异常
     */
    @ExceptionHandler(value = {AbstractException.class})
    public Result abstractException(HttpServletRequest request, AbstractException ex) {
        if (ex.getCause() != null) {
            log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex.toString(), ex.getCause());
            return Results.failure(ex);
        }
        log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex.toString());
        return Results.failure(ex);
    }

    /**
     * 拦截未捕获异常
     */
    @ExceptionHandler(value = Throwable.class)
    public Result defaultErrorHandler(HttpServletRequest request, Throwable throwable) {
        log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable);
        return Results.failure();
    }

    private String getUrl(HttpServletRequest request) {
        if (StringUtils.isEmpty(request.getQueryString())) {
            return request.getRequestURL().toString();
        }
        return request.getRequestURL().toString() + "?" + request.getQueryString();
    }
}

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

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

相关文章

CentOS7.9 利用 KubeKey 扩容 Kubernetes v1.26 Worker 节点实战

转载:CentOS7.9 利用 KubeKey 扩容 Kubernetes v1.26 Worker 节点实战 知识点 定级:入门级 KubeKey 安装部署 KubeSphere 和 Kubernetes KubeKey 定制化部署集群 KubeSphere v3.4.0 功能概览 Kubernetes 基本操作 CentOS 系统内核升级 演示服务器配…

Spring源码- context:component-scan base-package标签的作用源码解析

1.扫描包路径下所有的类加载解析成bean定义信息 ClassPathBeanDefinitionScanner .doScan方法调用路径 doScan:276, ClassPathBeanDefinitionScanner (org.springframework.context.annotation) parse:95, ComponentScanBeanDefinitionParser (org.springframework.context.a…

【用C语言编写】题目名称:数9的个数题目内容:编写程序数一下1到100的所有整数中出现多少个数字9

题目名称&#xff1a;数9的个数 题目内容&#xff1a;编写程序数一下1到100的所有整数中出现多少个数字9 代码如下&#xff1a; #include <stdio.h> int main() {int i 0;int count 0;for (i 1; i <100; i){if (i % 10 9) //个位为9的count;else if (i / 10 9) //…

手机应用的时间可以修改吗??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

Java线程安全之同步方法

同步方法 使用synchronized修饰的方法&#xff0c;就叫做同步方法&#xff0c;其固定格式如下&#xff1a; public [static] synchronized 返回值类型 同步方法() {可能会产生线程安全问题的代码 }注意事项&#xff1a; 同步方法可以是普通成员方法&#xff0c;也可以是sta…

聊一聊 webpack5性能优化有哪些?

介绍 此文章基于webpack5来阐述 webpack性能优化较多&#xff0c;可以对其进行分类 优化打包速度&#xff0c;开发或者构建时优化打包速度&#xff08;比如exclude、catch等&#xff09;优化打包后的结果&#xff0c;上线时的优化&#xff08;比如分包处理、减小包体积、CDN…

什么是安全生产痕迹化管理?如何做到生产过程中全程痕迹化管理?

安全生产痕迹化管理&#xff0c;简单来说&#xff0c;就是通过记录一些“信息”来确保安全工作的进展。这些方法包括记会议内容、写安全日记、拍照片、签字盖章、指纹识别、面部识别还有手机定位等。记录下来的文字、图片、数据和视频&#xff0c;就像一个个“脚印”&#xff0…

“免费”制作中国式报表的工具横空出世,内置丰富图表组件!

一.报表制作的烦恼 报表是我们日常工作中的好伙伴&#xff0c;它在企业管理和决策过程中扮演着重要角色&#xff0c;能够清晰直观地展示数据&#xff0c;让关键信息一目了然。 然而&#xff0c;无论是使用传统的手工报表还是基于软件的普通报表操作&#xff0c;都存在不便之处…

clickhouse sql 语法参考

clickhouse sql 语法参考 1. select1.1 将结果中的某些列与 re2 正则表达式匹配&#xff0c;可以使用 COLUMNS 表1.2 ARRAY JOIN - 数组数据平铺1.3 LEFT ARRAY JOIN 2. create2.1 分布式创建数据库2.2 分布式创建复制表2.4 CREATE TABLE [IF NOT EXISTS] [db.]table_name ENGI…

layui table 重新设置表格的高度

在layui的table模块中&#xff0c;如果使用table.render({})渲染了一个表格实例时&#xff0c;确定了height配置&#xff0c;后续用table.resize(id)方法重置表格尺寸时&#xff0c;表格的高度是不会变化的&#xff08;如果我的理解没有错的话&#xff09;。 有时我们希望根据…

ChatGPT在办公与科研中有怎样的应用?又是如何做论文撰写、数据分析、机器学习、深度学习及AI绘图

2022年11月30日&#xff0c;可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT-3.5&#xff0c;将人工智能的发展推向了一个新的高度。2023年11月7日&#xff0c;OpenAI首届开发者大会被称为“科技界的春晚”&#xff0c;吸引了全球广大…

8.1 字符串中等 43 Multiply Strings 38 Count and Say

43 Multiply Strings【默写】 那个难点我就没想先解决&#xff0c;原本想法是先想其他思路&#xff0c;但也没想出。本来只想chat一下使用longlong数据类型直接stoi()得不得行&#xff0c;然后就看到了答案&#xff0c;直接一个默写的大动作。但这道题确实考察的是还原乘法&…

C++(入门2)

承接上C&#xff08;入门1&#xff09;&#xff1a;CSDN 引用&#xff1a;&#xff08;类似指针但不同于指针&#xff0c;后续会将两则不同&#xff09; 概念 引⽤不是新定义⼀个变量&#xff0c;⽽是给已存在变量取了⼀个别名&#xff0c;编译器不会为引⽤变量开辟内存空间…

c语言第六天笔记

分支结构 分支结构&#xff1a;又被称之为选择结构 概念 选择结构&#xff1a;根据条件成立与否&#xff0c;选择相应的操作。 条件构建 关系表达式&#xff1a;含有关系运算符的表达式&#xff08;>,,&#xff09; 逻辑表达式&#xff1a;含有逻辑运算符的表达式&…

网络安全相关工作必须要有证书吗?

在当今数字化时代&#xff0c;网络安全已成为至关重要的领域。然而&#xff0c;对于从事网络安全相关工作的人员来说&#xff0c;证书是否是必不可少的呢? 一、网络安全证书的重要性 网络安全证书在一定程度上能够证明从业者具备相关的知识和技能。例如&#xff0c;CISP 作为国…

基于LLM开发AI应用竟如此简单

一、什么是LLM 随着人工智能技术的不断发展&#xff0c;越来越多的企业和机构开始将其应用于各个领域。其中&#xff0c;基于语言模型的人工智能技术&#xff08;LLM&#xff09;在自然语言处理、文本生成等方面表现出色&#xff0c;被广泛应用于各种场景中。 LLM是一种基于大…

你们要的“轮子”来了!67 个仓颉语言三方库正式公开!

01 Cangjie-TPC社区简介 Cangjie-TPC&#xff08;Third Party Components&#xff09;用于汇集基于仓颉编程语言开发的开源三方库&#xff0c;帮助开发者方便、快捷、高质量构建仓颉程序。 Cangjie-TPC社区联合软通动力、宝兰德、普元、上汽以及社区开发者共同完成第一批常用…

快速设置 terminator 透明背景

看图&#xff0c;按步骤设置后⭐重启一个终端则为透明效果 效果展示&#xff1a;

vscode+platformio开发小技巧

使用vscodeplatformio开发&#xff0c;具体安装配置文章很多&#xff0c;这里分享一些方便使用的小技巧&#xff0c;让使用体验在不增加学习成本的情况下更加丝滑。 1、配置依赖库 在使用vscode开发前&#xff0c;arduino环境遗留了一些库文件&#xff0c;这些第三方库可以通…

(20240801)矿山固废基胶凝材料及混凝土中文期刊整理

一、篇名:固废 级别:EI + 篇名:固废混凝土/水泥/胶砂/胶凝材料 级别:EI