SpringCloud 微服务下自定义异常传值问题

本文介绍了在SpringCloud微服务架构中如何实现自定义异常并传递错误码和数据。通过创建自定义异常类`MyException`,在微服务B中捕获并处理异常,然后在微服务A中使用`ErrorDecoder`进行异常解析,最终在全局异常处理类中进行响应。此方案使得异常信息能够跨服务传递并进行定制化处理。
摘要由CSDN通过智能技术生成

SpringCloud 微服务下自定义异常传值问题

1 需求描述

微服务A调用微服务B,此时微服务B需要抛出异常,且该异常需要携带自定义code,特殊数据data
但是直接像单服务全局捕获处理是无法使用code及data,为解决该问题需要修改相关内容。

2 自定义异常

package com.carfi.common.exception;

import com.carfi.common.constant.ApiHint;

/**
 * 自定义异常
* @author ll
* @date 2019年9月6日  
*    
*/ 
public class MyException extends RuntimeException{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Integer code;

	private Object data;

	public MyException(){}
	
	public MyException(Integer code, String msg){
		super(msg);
		this.code = code;
	}

	public MyException(Integer code, String msg, Object data){
		super(msg);
		this.code = code;
		this.data = data;
	}
	
	public Integer getCode() {
		return code;
	}

	public void setCode(Integer code) {
		this.code = code;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}
}

3 微服务B返回异常

继承DefaultErrorAttributes类,自定义返回code及data

package com.carfi.core.config;

import com.carfi.common.exception.MyException;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;

import java.util.Map;

/**
 * com.carfi.cxyapi.config$
 *
 * @author ll
 * @date 2021-03-29 16:20:00
 **/
@Component
@Primary
public class CustomErrorAttributes extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
        Throwable error = this.getError(webRequest);
        if (error instanceof MyException) {
            errorAttributes.put("code", ((MyException) error).getCode());
            errorAttributes.put("data", ((MyException) error).getData());
        }
        return errorAttributes;
    }
}

4 微服务A处理异常

自定义解析异常

package com.carfi.common.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.carfi.common.constant.ApiHint;
import com.carfi.common.exception.MyException;
import feign.Response;
import feign.Util;
import feign.codec.ErrorDecoder;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * com.carfi.common.exception$
 *
 * @author ll
 * @date 2021-03-29 15:21:49
 **/
@Configuration
public class MyExceptionDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        Exception exception = null;
        try {
            String json = Util.toString(response.body().asReader());
            Exception e = JSON.parseObject(json, Exception.class);
            e.printStackTrace();
            JSONObject jsonObject = JSONObject.parseObject(json);
            Object data = jsonObject.get("data");
            Integer code = jsonObject.getInteger("code");
            String message = JSONObject.parseObject(json).getString("message");
            if (message.contains("Load balancer does not have available server for client")) {
                return new MyException(ApiHint.SYS_BUSY);
            } else if (code == null) {
                return new MyException(ApiHint.OTHER);
            }
            return new MyException(code, message, data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return exception;
    }
}

全局异常处理

package com.carfi.cxyapi.exceptionhandler;

import com.carfi.common.constant.ApiHint;
import com.carfi.common.exception.MyException;
import com.carfi.common.pojo.ResObj;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.validation.ValidationException;

@ControllerAdvice(basePackages = {"com.carfi"})
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler({Exception.class, RuntimeException.class})
    @ResponseBody
    public ResObj doHandler(Exception e){
        ResObj error;
        if(e instanceof MyException){
            MyException me = (MyException) e;
            error = ResObj.error(me.getCode(),me.getMessage(),me.getData());
        } else if (e instanceof ValidationException) {
            ValidationException ve = (ValidationException) e;
            MyException myException = (MyException) ve.getCause();
            error = ResObj.error(myException.getCode(), myException.getMessage());
        } else {
            e.printStackTrace();
            if(e.getMessage().contains("Load balancer does not have available server for client")){
                error = ResObj.error(ApiHint.SYS_BUSY);
            }else{
                error = ResObj.error(ApiHint.OTHER);
            }
        }
        return error;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值