当前位置:   article > 正文

Spring Cloud 架构设计之全局异常处理及Feign异常传递_springcloud全局异常处理

springcloud全局异常处理

Spring Cloud 架构设计之全局异常处理

前言

近期,本人在开发一款互联网产品,项目地址https://github.com/yjjhkyq/doubi。同时,我也将通过连载的方式,将这款互联网产品的架构、技术细节等逐步记录下来,欢迎大家指正。

一、异常定义

public class ApiException extends RuntimeException
{
    private static final long serialVersionUID = 1L;

    private long code;

    private String message;

    public ApiException(String message)
    {
        this.message = message;
    }

    public ApiException(String message, long code)
    {
        this.message = message;
        this.code = code;
    }

    public ApiException(long code, String message)
    {
        this.message = message;
        this.code = code;
    }

    public ApiException(IErrorCode errorCode){
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
    }

    public ApiException(String message, Throwable e)
    {
        super(message, e);
        this.message = message;
    }

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

    public long getCode()
    {
        return code;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

当然,你还可以根据项目实际情况定义其他异常信息

二、全局捕获异常

、
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     * 请求方式不支持
     */
    @ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R handleException(HttpRequestMethodNotSupportedException e)
    {
        log.error(e.getMessage(), e);
        return R.fail("not support' " + e.getMethod() + "'req");
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R notFount(RuntimeException e)
    {
        log.error("server errror:", e);
        return R.fail("server errror:" + e.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R handleException(Exception e)
    {
        log.error(e.getMessage(), e);
        return R.fail("server errror");
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(ApiFeignException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R businessException(ApiFeignException e)
    {
        log.error("api feign exception {} {}", e.getCode(), e.getMessage());
        return R.build(e.getCode(), e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(ApiException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R businessException(ApiException e)
    {
        log.error("api exception {} {}", e.getCode(), e.getMessage());
        return R.build(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
    {
        List<ObjectError> errors =e.getBindingResult().getAllErrors();
        StringBuffer errorMsg=new StringBuffer();
        errors.stream().forEach(x -> errorMsg.append(x.getDefaultMessage()).append(";"));
        return R.build(ResultCode.VALIDATE_FAILED, errors);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

出现异常后,代码中通过@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)将HTTP状态码设置为500,这样设置有如下意义:

  • 如果是直接返回给前端,则明确告诉前端服务器出现了错误
  • 以便Feign的ErrorDecoder能够捕获,见下一章节

Feign异常传递:ErrorDecoder

在实际应用中,当通过Feign进行RPC调用的时候,如果上游的服务出现了异常,这时候我们希望在调用端能够通过try catch的方式捕获到,或者直接将异常传递给前端,怎么做呢,实现ErrorDecoder:

@Slf4j
@Configuration
public class FeignErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String s, Response response) {
        log.error("feign error, request url:{} status:{}", response.request().toString(), response.status());
        try {
            if (response.status() == HttpStatus.INTERNAL_SERVER_ERROR.value()){
                String body = IOUtils.toString(response.body().asReader(StandardCharsets.UTF_8));;
                return JsonUtil.parseObject(body, ApiException.class);
            }
            return errorStatus(s, response);
        }
        catch (Exception e){
            return e;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

总结

写完了,弱弱的问下,可以帮我的开源项目点个赞码?

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/84644
推荐阅读
相关标签
  

闽ICP备14008679号