Commit a9e19048 authored by liaozan's avatar liaozan 🏀

Improve exceptionHanding

parent e1f5d54c
...@@ -2,11 +2,14 @@ package com.schbrain.common.web; ...@@ -2,11 +2,14 @@ package com.schbrain.common.web;
import com.schbrain.common.web.exception.*; import com.schbrain.common.web.exception.*;
import com.schbrain.common.web.properties.WebProperties; import com.schbrain.common.web.properties.WebProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.stream.Collectors;
/** /**
* @author liaozan * @author liaozan
* @since 2023-05-08 * @since 2023-05-08
...@@ -16,8 +19,15 @@ public class ExceptionHandingConfiguration { ...@@ -16,8 +19,15 @@ public class ExceptionHandingConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public GlobalExceptionHandler defaultGlobalExceptionHandler() { public GlobalExceptionHandler defaultGlobalExceptionHandler(ObjectProvider<ExceptionTranslator> exceptionTranslators) {
return new DefaultGlobalExceptionHandler(); return new DefaultGlobalExceptionHandler(exceptionTranslators.orderedStream().collect(Collectors.toList()));
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(GlobalExceptionHandler.class)
public ExceptionTranslator defaultExceptionTranslator() {
return new DefaultExceptionTranslator();
} }
@Bean @Bean
......
package com.schbrain.common.web.exception;
import com.schbrain.common.exception.BaseException;
import com.schbrain.common.util.EnvUtils;
import com.schbrain.common.web.result.ResponseDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.Ordered;
/**
* @author liaozan
* @since 2023-06-01
*/
public class DefaultExceptionTranslator implements ExceptionTranslator {
@Override
public ResponseDTO<String> translate(Throwable throwable, int code, int action, String message) {
if (throwable instanceof BaseException) {
return ResponseDTO.error((BaseException) throwable);
}
if (EnvUtils.isProduction() || StringUtils.isBlank(message)) {
return ResponseDTO.error("系统错误", code);
}
return ResponseDTO.error(message, code, action);
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
\ No newline at end of file
...@@ -2,11 +2,10 @@ package com.schbrain.common.web.exception; ...@@ -2,11 +2,10 @@ package com.schbrain.common.web.exception;
import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.schbrain.common.constants.ResponseActionConstants;
import com.schbrain.common.exception.BaseException; import com.schbrain.common.exception.BaseException;
import com.schbrain.common.util.EnvUtils;
import com.schbrain.common.web.result.ResponseDTO; import com.schbrain.common.web.result.ResponseDTO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -37,11 +36,17 @@ import static com.schbrain.common.constants.ResponseCodeConstants.*; ...@@ -37,11 +36,17 @@ import static com.schbrain.common.constants.ResponseCodeConstants.*;
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler { public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler {
private final List<ExceptionTranslator> exceptionTranslators;
public DefaultGlobalExceptionHandler(List<ExceptionTranslator> exceptionTranslators) {
this.exceptionTranslators = exceptionTranslators;
}
/************************************* Base Exception Handing *************************************/ /************************************* Base Exception Handing *************************************/
@ExceptionHandler(BaseException.class) @ExceptionHandler(BaseException.class)
public ResponseDTO<String> handleBaseException(BaseException ex) { public ResponseDTO<String> handleBaseException(BaseException ex) {
logError(ex); logError(ex);
return ResponseDTO.error(ex); return buildResponse(ex, ex.getCode(), ex.getAction(), ex.getMessage());
} }
/************************************* Common Exception Handing *************************************/ /************************************* Common Exception Handing *************************************/
...@@ -185,25 +190,31 @@ public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler { ...@@ -185,25 +190,31 @@ public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler {
return buildResponse(ex, PARAM_INVALID, errorMsg); return buildResponse(ex, PARAM_INVALID, errorMsg);
} }
protected ResponseDTO<String> loggingThenBuildResponse(Throwable throwable, int errorCode) { protected ResponseDTO<String> loggingThenBuildResponse(Throwable throwable, int code) {
Throwable rootCause = ExceptionUtil.getRootCause(throwable); Throwable rootCause = ExceptionUtil.getRootCause(throwable);
logError(rootCause); logError(rootCause);
return buildResponse(rootCause, errorCode, rootCause.getMessage()); return buildResponse(rootCause, code, rootCause.getMessage());
} }
protected ResponseDTO<String> buildResponse(Throwable throwable, int code, String message) { protected ResponseDTO<String> buildResponse(Throwable throwable, int code, String message) {
boolean isProduction = EnvUtils.isProduction(); return buildResponse(throwable, code, ResponseActionConstants.ALERT, message);
ResponseDTO<String> responseDTO = getExceptionResponseMapping(throwable, isProduction); }
protected ResponseDTO<String> buildResponse(Throwable throwable, int code, int action, String message) {
ResponseDTO<String> responseDTO = translateException(throwable, code, action, message);
if (responseDTO != null) { if (responseDTO != null) {
return responseDTO; return responseDTO;
} }
if (isProduction || StringUtils.isBlank(message)) { return ResponseDTO.error(message, code, action);
return ResponseDTO.error("系统错误", code);
}
return ResponseDTO.error(message, code);
} }
protected ResponseDTO<String> getExceptionResponseMapping(Throwable throwable, boolean isProduction) { protected ResponseDTO<String> translateException(Throwable throwable, int code, int action, String message) {
for (ExceptionTranslator exceptionTranslator : exceptionTranslators) {
ResponseDTO<String> responseDTO = exceptionTranslator.translate(throwable, code, action, message);
if (responseDTO != null) {
return responseDTO;
}
}
return null; return null;
} }
...@@ -235,15 +246,7 @@ public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler { ...@@ -235,15 +246,7 @@ public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler {
protected void logError(Throwable throwable) { protected void logError(Throwable throwable) {
String exMsg = ExceptionUtil.getMessage(throwable); String exMsg = ExceptionUtil.getMessage(throwable);
if (hasCause(throwable)) {
exMsg = exMsg + ", " + ExceptionUtil.getRootCauseMessage(throwable);
throwable = ExceptionUtil.getRootCause(throwable);
}
log.error(exMsg, throwable); log.error(exMsg, throwable);
} }
private boolean hasCause(Throwable throwable) {
return throwable.getCause() != null;
}
} }
\ No newline at end of file
package com.schbrain.common.web.exception;
import com.schbrain.common.web.result.ResponseDTO;
import org.springframework.core.Ordered;
/**
* @author liaozan
* @since 2023-06-01
*/
@FunctionalInterface
public interface ExceptionTranslator extends Ordered {
/**
* Translate the exception to {@link ResponseDTO}
*/
ResponseDTO<String> translate(Throwable throwable, int code, int action, String message);
@Override
default int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 100;
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment