Mono.fromCallable 中的异常不会导致错误

Exception in Mono.fromCallable is not resulting in an error

我正在使用 Spring webflux 和 project reactor 在家庭项目中试用 kotlin。我正在尝试对 H2 数据库进行阻塞调用,因此我按照建议使用 fromCallable 方法。根据我的理解和经验,fromCallable 应该包装任何遇到的异常,然后可以使用 doOnError 处理这些异常,但是错误直接显示在控制台中。

fun updateUser(req: ServerRequest): Mono<ServerResponse> =
    req.bodyToMono(UserDto::class.java)
        .flatMap { userDto -> updateUser(userDto) }
        .flatMap { user -> ServerResponse.ok().syncBody(user!!) }
        .doOnError { ServerResponse.notFound().build() }

fun updateUser(userDto: UserDto): Mono<User?> =
    Mono.fromCallable {
        val id = userDto.id.toLong()
        userRepository.findByIdOrNull(id) ?: 
            throw IllegalArgumentException("No user found")
    }.subscribeOn(Schedulers.elastic())

如果我请求一个我的数据库中不存在的 ID,我会得到 404 返回。相反,我从请求中得到 500 返回,并且 IllegalArgumentException 直接进入 IDE 中的控制台。如果有人能告诉我这是为什么,或者有任何相关信息,将不胜感激!

doOnError 在单声道因错误终止时添加行为。换句话说,它增加了副作用但不会改变流。将 doOnError 替换为 onErrorResumeonErrorResume 它正是您所需要的,如果发生任何错误,它会订阅后备发布者。

fun updateUser(req: ServerRequest): Mono<ServerResponse> =
    req.bodyToMono(UserDto::class.java)
        .flatMap { userDto -> updateUser(userDto) }
        .flatMap { user -> ServerResponse.ok().syncBody(user!!) }
        .onErrorResume { ServerResponse.notFound().build() }       // fallback publisher
        .doOnError { println("Failed to perform an update: $it") } // side effect