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

时间:2019-05-23 17:45:31

标签: kotlin reactive-programming spring-webflux project-reactor

我正在使用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中的控制台。如果有人可以告诉我这是为什么,或者对此有任何信息,将不胜感激!

1 个答案:

答案 0 :(得分:1)

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