我有一个流:
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>
。
我可以想到一些丑陋的方法来做到这一点,但最干净的是什么?
答案 0 :(得分:1)
我建议你使用全局处理错误。我给你一个样本,这样你就可以得到这个想法。 (它是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))
}
}
}
答案 1 :(得分:0)
找到一个干净的答案:
all3again :: Int -> Int
all3again val =
ite cond1 f1 val
|> ite cond2 f2
|> ite cond3 f3
ite :: (a -> Bool) -> (a -> a) -> a -> a
ite c a v | c v = a v
| otherwise = v
(|>) :: a -> (a -> b) -> b
(|>) v f = f v
infixl 5 |>
onErrorReturnItem必须在地图之后,地图需要显式的类型参数。