Ver código fonte

新增全局异常

donglang 2 meses atrás
pai
commit
e3aad12114

+ 11 - 5
iot-platform-common/src/main/java/com/platform/enums/ErrorCodeEnum.java

@@ -17,6 +17,7 @@ public enum ErrorCodeEnum {
     RESOURCE_NOT_FOUND("100002", "资源不存在"),
     PERMISSION_DENIED("100003", "权限不足"),
     NETWORK_ERROR("100004", "网络连接异常"),
+    DB_OPERATE_FAIL("100005", "数据库操作异常"),
 
     // ====================== 设备相关错误(20000~29999)======================
     DEVICE_OFFLINE("200000", "设备离线"),
@@ -38,11 +39,16 @@ public enum ErrorCodeEnum {
     DATA_DELETE_FAIL("400002", "数据删除失败"),
     DB_CONNECTION_ERROR("400003", "数据库连接异常"),
 
-    // ====================== 时序数据存储错误(50000~59999)======================
-    TD_SAVE_FAIL("500000", "时序数据保存失败"),
-    TD_UPDATE_FAIL("500001", "时序数据更新失败"),
-    TD_DELETE_FAIL("500002", "时序数据删除失败"),
-    TD_CONNECTION_ERROR("500003", "时序数据库连接异常");
+    // ====================== 数据导出/导入错误(50000~59999)======================
+    DATA_IMPORT("500000", "数据导入失败"),
+    DATA_EXPORT("500001", "数据导出失败"),
+
+
+    // ====================== 时序数据存储错误(60000~69999)======================
+    TD_SAVE_FAIL("600000", "时序数据保存失败"),
+    TD_UPDATE_FAIL("600001", "时序数据更新失败"),
+    TD_DELETE_FAIL("600002", "时序数据删除失败"),
+    TD_CONNECTION_ERROR("600003", "时序数据库连接异常");
 
 
     /** 错误编码 */

+ 3 - 3
iot-platform-common/src/main/java/com/platform/exception/BaseResult.java

@@ -24,7 +24,7 @@ public class BaseResult<T> implements Serializable {
     /**
      * 错误码
      */
-    protected Integer code;
+    protected String code;
 
     /**
      * 错误信息
@@ -42,7 +42,7 @@ public class BaseResult<T> implements Serializable {
     public static <T> BaseResult<T> success(T data) {
         BaseResult<T> result = new BaseResult<>();
         result.setSuccess(true);
-        result.setCode(0);
+        result.setCode("0");
         result.setData(data);
         return result;
     }
@@ -57,7 +57,7 @@ public class BaseResult<T> implements Serializable {
     /**
      * 构建失败结果,返回错误信息
      */
-    public static <T> BaseResult<T> error(Integer code, String message) {
+    public static <T> BaseResult<T> error(String code, String message) {
         BaseResult<T> result = new BaseResult<>();
         result.setSuccess(false);
         result.setCode(code);

+ 0 - 35
iot-platform-common/src/main/java/com/platform/exception/BusinessException.java

@@ -1,35 +0,0 @@
-package com.platform.exception;
-
-import com.platform.enums.ErrorCodeEnum;
-import lombok.Getter;
-
-import static com.platform.enums.ErrorCodeEnum.SYSTEM_ERROR;
-
-/**
- * 业务异常类
- * @author PC
- */
-@Getter
-public class BusinessException extends RuntimeException {
-    
-    private final String code;
-    private final String message;
-    
-    public BusinessException(String message) {
-        super(message);
-        this.code = SYSTEM_ERROR.getCode();
-        this.message = message;
-    }
-    
-    public BusinessException(String code, String message) {
-        super(message);
-        this.code = code;
-        this.message = message;
-    }
-    
-    public BusinessException(ErrorCodeEnum errorCode) {
-        super(errorCode.getDesc());
-        this.code = errorCode.getCode();
-        this.message = errorCode.getDesc();
-    }
-}

+ 0 - 17
iot-platform-common/src/main/java/com/platform/exception/ErrorCode.java

@@ -1,17 +0,0 @@
-package com.platform.exception;
-
-/**
- * 错误码枚举接口
- */
-public interface ErrorCode {
-    
-    /**
-     * 获取错误码
-     */
-    Integer getCode();
-    
-    /**
-     * 获取错误信息
-     */
-    String getMessage();
-}

+ 112 - 0
iot-platform-common/src/main/java/com/platform/exception/GlobalExceptionHandler.java

@@ -0,0 +1,112 @@
+package com.platform.exception;
+
+
+import com.platform.enums.ErrorCodeEnum;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DataAccessException;
+import org.springframework.util.CollectionUtils;
+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.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.Set;
+
+/**
+ * Author: donglang
+ * Time: 2025-10-16
+ * Des: 全局异常处理器
+ * Version: 1.0
+ */
+
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler {
+
+
+    /**
+     * 理自定义业务异常(IotException)
+     * 场景:查询不到数据、数据过期、子表不存在等
+     */
+    @ExceptionHandler(IotException.class)
+    public BaseResult<Void> handlerIotException(IotException e, HttpServletRequest request) {
+        // 打印异常日志
+        log.warn("业务异常,请求路径:{},错误码:{}, 消息:{}", request.getRequestURI(), e.getErrorCode(), e.getMessage());
+        return BaseResult.error(e.getErrorCode(), e.getMessage());
+    }
+
+    /**
+     * 处理参数校验异常(@Validated 触发)
+     * 场景:车牌为空、运单号为空等参数错误
+     */
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public BaseResult<Void> handleValidationException(MethodArgumentNotValidException e, HttpServletRequest request) {
+        BindingResult bindingResult = e.getBindingResult();
+        // 拼接所有参数错误信息(如“车牌不能为空;运单号不能为空”)
+        StringBuilder errorMsg = new StringBuilder();
+
+        for (FieldError fieldError : bindingResult.getFieldErrors()) {
+            errorMsg.append(fieldError.getDefaultMessage()).append(";");
+
+        }
+        String finalMsg = !errorMsg.isEmpty() ? errorMsg.substring(0, errorMsg.length() - 1) : "参数校验失败";
+        // 打印异常日志
+        log.warn("参数校验异常,请求路径:{}, 消息:{}", request.getRequestURI(), finalMsg);
+        // 返回参数错误响应
+        return BaseResult.error(ErrorCodeEnum.PARAM_ERROR.getCode(), finalMsg);
+    }
+
+
+    /**
+     * 处理数据库相关异常(时序库/关系库操作失败)
+     * 场景:查询时序库时SQL错误、连接超时等
+     */
+    @ExceptionHandler({DataAccessException.class, java.sql.SQLException.class})
+    public BaseResult<Void> handleDbException(Exception e, HttpServletRequest request) {
+        // 打印异常日志
+        log.warn("数据库异常,请求路径:{}, 原因:{}", request.getRequestURI(), e.getMessage(), e);
+        return BaseResult.error(ErrorCodeEnum.DB_OPERATE_FAIL.getCode(), "数据库操作失败,请稍后重试");
+    }
+
+    /**
+     * 处理系统通用异常(未被上述方法捕获的异常)
+     * 场景:空指针、数组越界等未知错误
+     */
+    @ExceptionHandler(Exception.class)
+    public BaseResult<Void> handleSystemException(Exception e, HttpServletRequest request) {
+        // 打印异常日志
+        log.warn("数据库异常,请求路径:{}, 原因:{}", request.getRequestURI(), e.getMessage(), e);
+        return BaseResult.error(ErrorCodeEnum.SYSTEM_ERROR.getCode(), "系统内部错误,请联系管理员");
+    }
+
+    /**
+     * 处理非请求体参数校验异常
+     * 场景:queryRealTimeLocation方法的carNo为空(加了@NotBlank)
+     */
+    @ResponseBody
+    @ExceptionHandler(ConstraintViolationException.class)
+    public BaseResult<Object> constraintViolationExceptionHandler(ConstraintViolationException e, HttpServletRequest request) {
+        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
+        StringBuilder errorMsg = new StringBuilder();
+        if (!CollectionUtils.isEmpty(constraintViolations)) {
+            boolean first = true;
+            for (ConstraintViolation<?> constraintViolation : constraintViolations) {
+                if (!first) {
+                    errorMsg.append(",");
+                }
+                errorMsg.append(constraintViolation.getMessage());
+                first = false;
+            }
+        }
+        // 打印异常日志
+        log.warn("数据库异常,请求路径:{}, 原因:{}", request.getRequestURI(), e.getMessage());
+        return BaseResult.error(ErrorCodeEnum.PARAM_ERROR.getCode(), errorMsg.toString());
+    }
+
+
+}

+ 0 - 4
iot-platform-manager/src/main/java/com/platform/api/controller/TransferController.java

@@ -32,12 +32,8 @@ public class TransferController {
      */
     @PostMapping("/saveVehicleData")
     public BaseResult<Boolean> saveVehicleData(@RequestBody @Validated VehicleDataSaveRequest request) {
-        try {
             transferVehicleManage.saveVehicleData(request);
             return BaseResult.success(true);
-        } catch (Exception e) {
-            return BaseResult.error(-1, e.getMessage());
-        }
     }
 
     /**

+ 1 - 1
iot-platform-manager/src/main/java/com/platform/api/manager/TransferVehicleManage.java

@@ -86,7 +86,7 @@ public class TransferVehicleManage implements ApplicationContextAware {
             // 批量保存到时序数据库
             taosMapper.batchInsertVehicleData(vehicleDataList);
         } catch (Exception e) {
-            throw new IotException(ErrorCodeEnum.TD_SAVE_FAIL, "批量保存车辆数据到时序数据库失败");
+            throw new IotException(ErrorCodeEnum.TD_SAVE_FAIL, "批量保存车辆数据到时序数据库失败", e);
         }
     }
 

+ 4 - 5
iot-platform-manager/src/main/java/com/platform/manage/IotDeviceManage.java

@@ -10,7 +10,6 @@ import com.platform.entity.IotDevice;
 import com.platform.entity.IotDeviceGroup;
 import com.platform.entity.IotMod;
 import com.platform.enums.ErrorCodeEnum;
-import com.platform.exception.BusinessException;
 import com.platform.exception.IotException;
 import com.platform.exception.PageResult;
 import com.platform.request.device.IotDeviceDetailRequest;
@@ -103,7 +102,7 @@ public class IotDeviceManage {
     public Boolean addDevice(IotDeviceSaveRequest request) {
         IotDevice oneByName = iotDeviceService.getOneByName(request.getDeviceName());
         if (Objects.nonNull(oneByName)) {
-            throw new BusinessException("设备名称已存在");
+            throw new IotException(ErrorCodeEnum.DATA_SAVE_FAIL, "设备名称已存在");
         }
         IotDevice iotDevice = IotDevice.toIotDevice(request);
         return iotDeviceService.save(iotDevice);
@@ -168,7 +167,7 @@ public class IotDeviceManage {
         try {
             EasyExcelUtil.exportTemplate("设备导入模板", DeviceExcelTemplateDTO.class, response);
         } catch (Exception e) {
-            throw new BusinessException("设备导入模板异常");
+            throw new IotException(ErrorCodeEnum.DATA_EXPORT, "设备导入模板异常");
         }
         return null;
     }
@@ -181,14 +180,14 @@ public class IotDeviceManage {
      */
     public Void importExcel(MultipartFile file) {
         if (file.isEmpty()) {
-            throw new BusinessException("文件不能为空");
+            throw new IotException(ErrorCodeEnum.DATA_IMPORT, "文件不能为空");
         }
         try {
             InputStream inputStream = file.getInputStream();
             List<IotDeviceResp> deviceDetailReqs = EasyExcelUtil.importExcel(inputStream, IotDeviceResp.class);
             //todo cxf 导入设备
         } catch (Exception e) {
-            throw new BusinessException("设备导入异常");
+            throw new IotException(ErrorCodeEnum.DATA_IMPORT, "设备导入异常");
         }
         return null;
     }