gateway动态路由异常处理方式你知道吗

443 阅读1分钟

刷新路由异常catch

动态路由就不聊咯,直接上代码。这是刷新路由的操作,在这里我们catch了异常,但是当我们的路由信息配置不正确刷新路由错误的时候我们并不能catch到异常。如果我们做了后台管理页面,前端收到的信息是成功,但是结果并没有成功,因为我们不知道刷新路由失败了。

try {
    routeDefinitionWriter.save(Mono.just(definition)).subscribe();
    this.publisher.publishEvent(new RefreshRoutesEvent(this));
} catch (Exception e) {
    log.info("刷新路由失败:{}", ExceptionUtil.getMessage(e));
    throw new RuntimeException(e.getMessage());
}

问题分析

这是为什么呢?直接上代码。找到到RefreshRoutesEvent的实现。最后找到包路径: org.springframework.cloud.gateway.route.CachingRouteLocator 我们看见异常的处理在handleRefreshError这个方法中处理的

public void onApplicationEvent(RefreshRoutesEvent event) {
    try {
        this.fetch().collect(Collectors.toList()).subscribe((list) -> {
            Flux.fromIterable(list).materialize().collect(Collectors.toList()).subscribe((signals) -> {
                this.applicationEventPublisher.publishEvent(new RefreshRoutesResultEvent(this));
                this.cache.put("routes", signals);
            }, (throwable) -> {
            //异常处理
                this.handleRefreshError(throwable);
            });
        });
    } catch (Throwable var3) {
     //异常处理
        this.handleRefreshError(var3);
    }

}

在这里我们看见只是打印了异常信息,并没有把异常信息抛出。所以我们在控制台会看见异常信息,但是并没有catch到异常。我们看见spring把异常放在了RefreshRoutesResultEvent这个事件中

private void handleRefreshError(Throwable throwable) {
    if (log.isErrorEnabled()) {
        //异常信息打印
        log.error("Refresh routes error !!!", throwable);
    }
    //异常处理
    this.applicationEventPublisher.publishEvent(new RefreshRoutesResultEvent(this, throwable));
}

问题处理

我这里的处理方式是我监听了RefreshRoutesResultEvent这个事件,如果throwable属性不为空表示刷新路由出现了异常,我获取异常信息把异常抛出。后台管理页面能看到刷新路由失败了以及异常的具体信息。

@EventListener
public void handleEvent(RefreshRoutesResultEvent refreshRoutesResultEvent){
    Throwable throwable = refreshRoutesResultEvent.getThrowable();
    if(throwable != null){
        throw new RuntimeException(throwable.getCause().getMessage());
    }
}