57 lines
3.0 KiB
Java
57 lines
3.0 KiB
Java
package com.yunhai.cms.controller.api;
|
||
|
||
import com.yunhai.platform.apistd.ApiResponse;
|
||
import com.yunhai.platform.utils.exception.ErrorCode;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.core.Ordered;
|
||
import org.springframework.core.convert.ConversionFailedException;
|
||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||
import org.springframework.core.annotation.Order;
|
||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||
|
||
/**
|
||
* 管理端参数级异常翻译(体检 H-1/H-4 根因修复)。
|
||
*
|
||
* <p>平台 GlobalExceptionHandler 只兜 @Valid 校验/BizException/全局 Exception,
|
||
* 三类 Spring MVC 参数绑定异常(缺参/类型不匹配/请求体不可读)落入兜底分支被
|
||
* 报成 code=6 "内部服务错误"。本 advice 以更高优先级把它们翻译回 code=2 参数错误,
|
||
* 前端可提示、日志不再噪音;真正的业务/系统异常不受影响(仍走平台处理器,堆栈完整)。
|
||
*/
|
||
@Slf4j
|
||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||
@RestControllerAdvice(basePackages = "com.yunhai.cms.controller.api")
|
||
public class ApiParamExceptionHandler {
|
||
|
||
@ExceptionHandler(MissingServletRequestParameterException.class)
|
||
public ApiResponse<Object> missingParam(MissingServletRequestParameterException e) {
|
||
log.warn("管理端缺必填参数: {}", e.getParameterName());
|
||
return ApiResponse.fail(ErrorCode.PARAM_ERROR, "缺少必填参数:" + e.getParameterName());
|
||
}
|
||
|
||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||
public ApiResponse<Object> typeMismatch(MethodArgumentTypeMismatchException e) {
|
||
String expected = e.getRequiredType() == null ? "" : "(应为 " + e.getRequiredType().getSimpleName() + ")";
|
||
log.warn("管理端参数类型不匹配: {}={}", e.getName(), e.getValue());
|
||
return ApiResponse.fail(ErrorCode.PARAM_ERROR, "参数格式不正确:" + e.getName() + expected);
|
||
}
|
||
|
||
/** JSON 解析失败:编码/语法/时间格式(jackson date-format yyyy-MM-dd HH:mm:ss) */
|
||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||
public ApiResponse<Object> unreadable(HttpMessageNotReadableException e) {
|
||
Throwable cause = e.getCause() == null ? e : e.getCause();
|
||
String hint = cause.getMessage() == null ? "" : ": " + firstLine(cause.getMessage());
|
||
log.warn("管理端请求体不可读 {}", firstLine(hint));
|
||
return ApiResponse.fail(ErrorCode.PARAM_ERROR,
|
||
"请求体格式错误(JSON/UTF-8/时间格式,时间需 yyyy-MM-dd HH:mm:ss)");
|
||
}
|
||
|
||
private static String firstLine(String s) {
|
||
int i = s.indexOf('\n');
|
||
String line = i < 0 ? s : s.substring(0, i);
|
||
return line.length() > 120 ? line.substring(0, 120) : line;
|
||
}
|
||
}
|