You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin非空断言抛出NPE,如何转为Mono.error让onErrorResume捕获?

问题描述

我在Kotlin中编写了一个函数,调用方法时使用了非空断言,代码如下:

saveEntity(param1!!, param2!!)
 .onErrorResume {
    logger.error("Exception caught", it)
    Mono.just(someObject)
 } 

注:saveEntity方法返回Mono<someObject>。问题在于,当param1或param2为null时会抛出NullPointerException,但该异常不属于Mono类型,无法通过onErrorResume处理。请问能否通过三元运算等方式在函数调用时抛出Mono.error,使该异常可被onErrorResume捕获?

解决方案

当然可以,核心思路是让参数校验的异常发生在Reactor流的上下文内,这样异常会被Mono封装,进而能被onErrorResume捕获处理。以下是几种可行的实现方式:

方式一:显式校验+Mono.defer

用Mono.defer包裹参数校验与方法调用,确保所有异常都进入Mono流:

Mono.defer {
    val validParam1 = param1 ?: throw NullPointerException("param1 must not be null")
    val validParam2 = param2 ?: throw NullPointerException("param2 must not be null")
    saveEntity(validParam1, validParam2)
}
.onErrorResume {
    logger.error("Exception caught", it)
    Mono.just(someObject)
}

也可以替换成IllegalArgumentException,提供更明确的错误提示,比原生NPE更友好。

方式二:三元/条件判断直接返回Mono.error

如果偏好简洁的条件判断,可提前拦截空参数场景,直接返回错误Mono:

val resultMono = if (param1 == null || param2 == null) {
    Mono.error(NullPointerException("param1 or param2 is null"))
} else {
    saveEntity(param1, param2)
}

resultMono.onErrorResume {
    logger.error("Exception caught", it)
    Mono.just(someObject)
}

这种方式逻辑直白,空参数的情况不会进入saveEntity调用,直接触发错误流。

方式三:Mono.fromCallable封装断言调用

如果想保留!!断言,可将调用逻辑放入fromCallable中,让异常被Mono捕获:

Mono.fromCallable {
    saveEntity(param1!!, param2!!)
}
.flatMap { it }
.onErrorResume {
    logger.error("Exception caught", it)
    Mono.just(someObject)
}

不过这种方式依赖断言的隐式抛出,可读性不如显式校验,不推荐作为首选方案。

内容的提问来源于stack exchange,提问作者Aditya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 15:37:12