【问题标题】:Exception in Mono.fromCallable is not resulting in an errorMono.fromCallable 中的异常不会导致错误
【发布时间】:2019-05-23 17:45:31
【问题描述】:

我正在使用 Spring webflux 和项目反应器在家庭项目中尝试 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 中的控制台。如果有人能告诉我这是为什么,或者有任何相关信息,将不胜感激!

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 你说得完全正确,有点遗憾的是我没有注意到……我在编写 fromCallable 时遇到了一些语法问题,所以我认为问题出在那个函数上。感谢您清理它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多