[英]Catch an error and return a new type in RxJava2
我有一個流:
val symbols: Single<List<Symbol>>
現在,我想使用map()將流轉換為UI狀態:
private fun cool(): Single<SymbolContract.State> =
symbols.map { SymbolContract.State.Symbols(it) }
我想要做的是在單個上游symbols
上捕獲一個錯誤,以便可以捕獲任何錯誤,然后返回SymbolContract.State.GeneralError()
。
我想要類似onErrorMap()
東西。 不幸的是,將onErrorResumeItem
放在symbols
上不起作用,因為它需要返回List<Symbol>
。
我可以想到一些丑陋的方法,但是最干凈的是什么?
我建議您使用全局處理錯誤。 我給你一個樣本,這樣你就可以理解。 (這是kotlin),您可以捕獲盡可能多的異常,其中一些是我自定義的異常。 請記住,此示例是關於Reactive Webflux的,但是您明白了。 在其他地方也差不多
@Configuration
class ExceptionTranslator {
@Bean
@Order(-1)
fun handle(objectMapper: ObjectMapper): ErrorWebExceptionHandler {
return ErrorWebExceptionHandler { exchange, ex ->
if (exchange.response.isCommitted) {
return@ErrorWebExceptionHandler Mono.error(ex)
}
val response = exchange.response
response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR
response.headers.contentType = MediaType.APPLICATION_PROBLEM_JSON_UTF8
val url: String
var message = ex.message
var params = mutableMapOf<String, Any>()
when (ex) {
is ParametricException -> {
url = ex.url
params = ex.params
}
is BaseException -> {
url = ex.url
}
is BadCredentialsException -> {
url = INVALID_CREDENTIAL_TYPE
message = ex.message ?: "Wrong Credentials"
}
is ConcurrencyFailureException -> {
url = INTERNAL_TYPE
message = ERR_CONCURRENCY_FAILURE
}
is MethodArgumentNotValidException -> {
val result = ex.bindingResult
val fieldErrors = result.fieldErrors.map {
FieldErrorVM(it.objectName, it.field, it.code ?: "Unknown")
}
url = CONSTRAINT_VIOLATION_TYPE
message = ERR_VALIDATION
params = Collections.singletonMap("errors", fieldErrors)
}
else -> url = INTERNAL_TYPE
}
if (ex is BaseException) {
response.statusCode = HttpStatus.valueOf(ex.status.code())
}
val bytes = objectMapper.writeValueAsBytes(ProblemVM(url, message ?: "Internal Error", params))
val buffer = response.bufferFactory().wrap(bytes)
response.writeWith(Mono.just(buffer))
}
}
}
找到一個明確的答案:
private fun symbols(): Single<SymbolContract.State> =
symbols.map<SymbolContract.State> { SymbolContract.State.Symbols(it) }
.onErrorReturnItem(SymbolContract.State.Error(SymbolContract.State.Error.Type.Network))
onErrorReturnItem必須位於映射之后,並且映射需要顯式類型參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.