Zuul provides filer and router functions in the springcloud microservice system, which is an indispensable part of microservices. In addition to the default implementation of filer, it can also customize authorization, current limiting, security verification, etc., and router can completely replace Nginx reverse proxy. Zuul exception handling is done by SendErrorFilter.
During our application process, we found that there are two problems that are not very friendly to use the default exception filter:
1. It is impossible to quickly identify whether the service requesting route is timed out or there are no available nodes. If an error occurs, you can only view the log and locate it through the stack;
2. Unable to compatible with custom response package formats such as {code:500,msg:”xx error”} format.
Next we are discussing how to customize exception handling, customize exception prompt information, etc.
First of all, we must disable the default SendErrorFilter. The official has provided the switch configuration, so you can configure it directly.
zuul.SendErrorFilter.post.disable=true
Custom ErrorFilter, I won't say much here, just post the code
public class ErrorFilter extends ZuulFilter { private static final String ERROR_STATUS_CODE_KEY = "error.status_code"; private Logger log = LoggerFactory.getLogger(ErrorFilter.class); public static final String DEFAULT_ERR_MSG = "The system is busy, please try again later"; @Override public String filterType() { return "post"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); return ctx.containsKey(ERROR_STATUS_CODE_KEY); } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); try { HttpServletRequest request = ctx.getRequest(); int statusCode = (Integer) ctx.get(ERROR_STATUS_CODE_KEY); String message = (String) ctx.get("error.message"); if (ctx.containsKey("error.exception")) { Throwable e = (Exception) ctx.get("error.exception"); Throwable re = getOriginException(e); if(re instanceof java.net.ConnectException){ message = "Real Service Connection refused"; log.warn("uri:{},error:{}" ,request.getRequestURI(),re.getMessage()); }else if(re instanceof java.net.SocketTimeoutException){ message = "Real Service Timeout"; log.warn("uri:{},error:{}" ,request.getRequestURI(),re.getMessage()); }else if(re instanceof com.netflix.client.ClientException){ message = re.getMessage(); log.warn("uri:{},error:{}" ,request.getRequestURI(),re.getMessage()); }else{ log.warn("Error during filtering",e); } } if(StringUtils.isBlank(message))message = DEFAULT_ERR_MSG; request.setAttribute("javax.servlet.error.status_code", statusCode); request.setAttribute("javax.servlet.error.message", message); WebUtils.responseOutJson(ctx.getResponse(), JsonUtils.toJson(new WrapperResponse<>(statusCode, message))); } catch (Exception e) { String error = "Error during filtering[ErrorFilter]"; log.error(error,e); WebUtils.responseOutJson(ctx.getResponse(), JsonUtils.toJson(new WrapperResponse<>(500, error))); } return null; } private Throwable getOriginException(Throwable e){ e = e.getCause(); while(e.getCause() != null){ e = e.getCause(); } return e; }}Finally register our custom ErrorFilter
@Bean public ErrorFilter errorFilter(){ return new ErrorFilter();}Summarize
The above is the Spring Cloud zuul custom unified exception handling implementation method introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!