序
使用zuul作为api网关的话,经常会碰见一些异常,这里小结一下。
ZuulException
这个是最外层的异常
public class ZuulException extends Exception {
public int nStatusCode;
public String errorCause;
/**
* Source Throwable, message, status code and info about the cause
* @param throwable
* @param sMessage
* @param nStatusCode
* @param errorCause
*/
public ZuulException(Throwable throwable, String sMessage, int nStatusCode, String errorCause) {
super(sMessage, throwable);
this.nStatusCode = nStatusCode;
this.errorCause = errorCause;
incrementCounter("ZUUL::EXCEPTION:" + errorCause + ":" + nStatusCode);
}
/**
* error message, status code and info about the cause
* @param sMessage
* @param nStatusCode
* @param errorCause
*/
public ZuulException(String sMessage, int nStatusCode, String errorCause) {
super(sMessage);
this.nStatusCode = nStatusCode;
this.errorCause = errorCause;
incrementCounter("ZUUL::EXCEPTION:" + errorCause + ":" + nStatusCode);
}
/**
* Source Throwable, status code and info about the cause
* @param throwable
* @param nStatusCode
* @param errorCause
*/
public ZuulException(Throwable throwable, int nStatusCode, String errorCause) {
super(throwable.getMessage(), throwable);
this.nStatusCode = nStatusCode;
this.errorCause = errorCause;
incrementCounter("ZUUL::EXCEPTION:" + errorCause + ":" + nStatusCode);
}
private static final void incrementCounter(String name) {
CounterFactory.instance().increment(name);
}
}
RibbonRoutingFilter
spring-cloud-netflix-core-1.2.6.RELEASE-sources.jar!/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java
这个类抛了很多ZuulException:
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
this.helper.addIgnoredHeaders();
try {
RibbonCommandContext commandContext = buildCommandContext(context);
ClientHttpResponse response = forward(commandContext);
setResponse(response);
return response;
}
catch (ZuulException ex) {
context.set(ERROR_STATUS_CODE, ex.nStatusCode);
context.set("error.message", ex.errorCause);
context.set("error.exception", ex);
}
catch (Exception ex) {
context.set("error.status_code",
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
context.set("error.exception", ex);
}
return null;
}
forward
protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception {
Map<String, Object> info = this.helper.debug(context.getMethod(),
context.getUri(), context.getHeaders(), context.getParams(),
context.getRequestEntity());
RibbonCommand command = this.ribbonCommandFactory.create(context);
try {
ClientHttpResponse response = command.execute();
this.helper.appendDebug(info, response.getStatusCode().value(),
response.getHeaders());
return response;
}
catch (HystrixRuntimeException ex) {
return handleException(info, ex);
}
}
这里有一个HystrixRuntimeException,主要是跟hystrix相关的,比如超时等。
handleException
protected ClientHttpResponse handleException(Map<String, Object> info,
HystrixRuntimeException ex) throws ZuulException {
int statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
Throwable cause = ex;
String message = ex.getFailureType().toString();
ClientException clientException = findClientException(ex);
if (clientException == null) {
clientException = findClientException(ex.getFallbackException());
}
if (clientException != null) {
if (clientException
.getErrorType() == ClientException.ErrorType.SERVER_THROTTLED) {
statusCode = HttpStatus.SERVICE_UNAVAILABLE.value();
}
cause = clientException;
message = clientException.getErrorType().toString();
}
info.put("status", String.valueOf(statusCode));
throw new ZuulException(cause, "Forwarding error", statusCode, message);
}
findClientException
protected ClientException findClientException(Throwable t) {
if (t == null) {
return null;
}
if (t instanceof ClientException) {
return (ClientException) t;
}
return findClientException(t.getCause());
}
com.netflix.client.ClientException
public class ClientException extends Exception{
/**
*
*/
private static final long serialVersionUID = -7697654244064441234L;
/**
* define your error codes here
*
*/
public enum ErrorType{
GENERAL,
CONFIGURATION,
NUMBEROF_RETRIES_EXEEDED,
NUMBEROF_RETRIES_NEXTSERVER_EXCEEDED,
SOCKET_TIMEOUT_EXCEPTION,
READ_TIMEOUT_EXCEPTION,
UNKNOWN_HOST_EXCEPTION,
CONNECT_EXCEPTION,
CLIENT_THROTTLED,
SERVER_THROTTLED,
NO_ROUTE_TO_HOST_EXCEPTION,
CACHE_MISSING;
static String getName(int errorCode){
if (ErrorType.values().length >= errorCode){
return ErrorType.values()[errorCode].name();
}else{
return "UNKNOWN ERROR CODE";
}
}
}
//...
}