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
相关产品推荐
相关产品推荐

