0

所以我对 rx-java/rx-kotlin 完全陌生,直到我在 Micronaut 中编写 HTTP 过滤器(https://docs.micronaut.io/latest/guide/index.html# filters)这让我措手不及,因为我只做了常规的 JAX-RS 过滤器。

所以在做了一些试验和错误之后,我想出了这个。

 return Flowable.fromPublisher(remoteClient.getPermissions(userId))
        .subscribeOn(Schedulers.io())
        .onErrorReturn { e ->
            logger.error("Error when fetching users from remote service", e)
            emptyList()
        }
        .switchMap { permissions ->
            if (permissions.contains(somePermission)) {
                chain.proceed(request)
            } else {
                val response = HttpResponseFactory.INSTANCE.status(
                    HttpStatus.FORBIDDEN,
                    "No user found"
                )
                Flowable.just(response)
            }
        }

代码被重写,但点仍然存在。这里有一些改进的空间。

我想做的是改进异常处理并在抛出异常的情况下返回 500(例如,如果remoteClient无法访问所调用的远程服务。我怎样才能做到这一点?我没有其他任何东西除了上面的解决方案之外的工作,为下一个观察者返回一个空列表。

4

1 回答 1

1

您可以在onErrorReturn运算符之后移动运算switchMap符。如果getPermissions发出错误,执行将跳过您的switchMap, 并在onErrorReturn:

 return Flowable.fromPublisher(remoteClient.getPermissions(userId))
        .subscribeOn(Schedulers.io())
        .switchMap { permissions ->
            if (permissions.contains(somePermission)) {
                chain.proceed(request)
            } else {
                val response = HttpResponseFactory.INSTANCE.status(
                    HttpStatus.FORBIDDEN,
                    "No user found"
                )
                Flowable.just(response)
            }
        }
        .onErrorReturn { e ->
            logger.error("Error when fetching users from remote service", e)
            val response = // whatever
            return response
        }

请注意,内部发生的异常switchMap也会导致onErrorReturn执行。因此,您要么想要检查传入的 Exception onErrorReturn以决定使用什么响应,要么嵌入一个onErrorReturninside of switchMap,链接到chain.proceed(request)调用,以防止它向下游发出异常。

于 2020-06-05T14:30:31.170 回答