cc.shacocloud.mirage.web.ExceptionHandlerExceptionResolver Maven / Gradle / Ivy
package cc.shacocloud.mirage.web;
import cc.shacocloud.mirage.utils.SelfSortList;
import cc.shacocloud.mirage.web.bind.annotation.ExceptionHandler;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import org.jetbrains.annotations.Nullable;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.OrderUtils;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 一个{@link AbstractHandlerExceptionResolver},它通过{@link ExceptionHandler}方法解决异常。
*
* @see ExceptionHandlerMethodResolver
*/
public class ExceptionHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
private final List exceptionHandlerResolvers
= new SelfSortList<>(n -> OrderUtils.getOrder(n.getClass(), Ordered.LOWEST_PRECEDENCE));
private final Map, InvocableHandlerMethod> exceptionMethodHandlerCache =
new ConcurrentHashMap<>(128);
/**
* 注册异常映射处理器
*
* @param exceptionHandler 异常处理器类
*/
public void registerExceptionHandler(Object exceptionHandler) {
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(exceptionHandler);
if (resolver.hasExceptionMappings()) {
this.exceptionHandlerResolvers.add(resolver);
}
}
@Override
protected Future doResolveException(HttpRequest request, HttpResponse response,
VertxInvokeHandler handler, Throwable cause) {
InvocableHandlerMethod handlerMethod = getExceptionHandlerMethod(cause);
if (handlerMethod == null) return Future.succeededFuture();
return handler.invokeAndHandleHandlerMethod(request.context(), handlerMethod, cause, cause.getCause(), handler.getHandler());
}
/**
* 为给定异常找到一个{@code @ExceptionHandler}方法并且封装{@link InvocableHandlerMethod}
*/
@Nullable
protected InvocableHandlerMethod getExceptionHandlerMethod(Throwable cause) {
InvocableHandlerMethod handlerMethod = this.exceptionMethodHandlerCache.get(cause.getClass());
if (handlerMethod == null) {
for (ExceptionHandlerMethodResolver exceptionHandlerResolver : exceptionHandlerResolvers) {
Method method = exceptionHandlerResolver.resolveMethodByThrowable(cause);
if (method != null) {
handlerMethod = new InvocableHandlerMethod(exceptionHandlerResolver.getExceptionHandler(), method);
this.exceptionMethodHandlerCache.put(cause.getClass(), handlerMethod);
break;
}
}
}
return handlerMethod;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy