All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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