如何处理 monix onErrorHandle 中抛出的未处理异常
How to handle unhandled exception throw in monix onErrorHandle
我正在使用 monix 任务,我正在尝试捕获 Throwable,然后将其转换为自定义错误。我有 removed/changed 简单且相关的代码。这是代码(问题跟在代码片段之后):
import io.netty.handler.codec.http.HttpRequest
import monix.reactive.Observable
import io.netty.buffer.ByteBuf
import monix.eval.Task
import com.mypackage.Response
private[this] def handler(
request: HttpRequest,
body: Observable[ByteBuf]
): Task[Response] = {
val localPackage = for {
failfast <- Task.eval(1 / 0)
} yield failfast
// Failure case.
localPackage.onErrorRecoverWith {
case ex: ArithmeticException =>
print(s"LOG HERE^^^^^^^^^^^^^^^")
return Task.now(
Response(HttpResponseStatus.BAD_REQUEST,
None,
None)
)
}.runAsync
// Success case.
localPackage.map { x =>
x match {
case Right(cool) =>
Response(
HttpResponseStatus.OK,
None,
cool
)
case Left(doesntmatter) => ???
}
}
}
我能够看到打印语句,但预期的 Task.now(Response(...
没有被 return 编辑。相反,调用处理程序方法的方法会抛出错误。我如何使 return 成为 Task[Response]
?
成功案例有效,失败案例无效。
编辑 #1:修复 scala 代码中的错误。
编辑 #2 我就是这样修复的。
// Success case.
localPackage.map { x =>
x match {
case Right(cool) =>
Response(
HttpResponseStatus.OK,
None,
cool
)
case Left(doesntmatter) => ???
}
}.onErrorRecoverWith {
case ex: ArithmeticException =>
print(s"LOG HERE^^^^^^^^^^^^^^^")
return Task.now(
Response(HttpResponseStatus.BAD_REQUEST,
None,
None)
)
}
我考虑的是未来,忘记了任务的 lazy eval
性质。我还了解了 CancellableFuture
值是如何在失败任务中被丢弃的。
你的样品有几个问题。
其中一个代码在 Scala 中无效:
val localPackage = for {
failfast <- 1 / 0
} yield failfast
我猜你的意思是 Task.eval(1 / 0)
。
另外 onErrorHandle
没有 Task
作为 return 类型,您可能在想 onErrorHandleWith
。给它一个部分函数(即一个可以因匹配错误而抛出异常的函数)是一个非常糟糕的主意——如果你想匹配那个错误,那么更好的选择是 onErrorRecover
和 onErrorRecoverWith
, 以偏函数为参数。
这是一个示例:
import monix.eval._
import monix.execution.Scheduler.Implicits.global
val task = Task.eval(1 / 0).onErrorRecoverWith {
case _: ArithmeticException => Task.now(Int.MinValue)
}
task.runAsync.foreach(println)
//=> -2147483648
希望对您有所帮助。
我正在使用 monix 任务,我正在尝试捕获 Throwable,然后将其转换为自定义错误。我有 removed/changed 简单且相关的代码。这是代码(问题跟在代码片段之后):
import io.netty.handler.codec.http.HttpRequest
import monix.reactive.Observable
import io.netty.buffer.ByteBuf
import monix.eval.Task
import com.mypackage.Response
private[this] def handler(
request: HttpRequest,
body: Observable[ByteBuf]
): Task[Response] = {
val localPackage = for {
failfast <- Task.eval(1 / 0)
} yield failfast
// Failure case.
localPackage.onErrorRecoverWith {
case ex: ArithmeticException =>
print(s"LOG HERE^^^^^^^^^^^^^^^")
return Task.now(
Response(HttpResponseStatus.BAD_REQUEST,
None,
None)
)
}.runAsync
// Success case.
localPackage.map { x =>
x match {
case Right(cool) =>
Response(
HttpResponseStatus.OK,
None,
cool
)
case Left(doesntmatter) => ???
}
}
}
我能够看到打印语句,但预期的 Task.now(Response(...
没有被 return 编辑。相反,调用处理程序方法的方法会抛出错误。我如何使 return 成为 Task[Response]
?
成功案例有效,失败案例无效。
编辑 #1:修复 scala 代码中的错误。
编辑 #2 我就是这样修复的。
// Success case.
localPackage.map { x =>
x match {
case Right(cool) =>
Response(
HttpResponseStatus.OK,
None,
cool
)
case Left(doesntmatter) => ???
}
}.onErrorRecoverWith {
case ex: ArithmeticException =>
print(s"LOG HERE^^^^^^^^^^^^^^^")
return Task.now(
Response(HttpResponseStatus.BAD_REQUEST,
None,
None)
)
}
我考虑的是未来,忘记了任务的 lazy eval
性质。我还了解了 CancellableFuture
值是如何在失败任务中被丢弃的。
你的样品有几个问题。
其中一个代码在 Scala 中无效:
val localPackage = for {
failfast <- 1 / 0
} yield failfast
我猜你的意思是 Task.eval(1 / 0)
。
另外 onErrorHandle
没有 Task
作为 return 类型,您可能在想 onErrorHandleWith
。给它一个部分函数(即一个可以因匹配错误而抛出异常的函数)是一个非常糟糕的主意——如果你想匹配那个错误,那么更好的选择是 onErrorRecover
和 onErrorRecoverWith
, 以偏函数为参数。
这是一个示例:
import monix.eval._
import monix.execution.Scheduler.Implicits.global
val task = Task.eval(1 / 0).onErrorRecoverWith {
case _: ArithmeticException => Task.now(Int.MinValue)
}
task.runAsync.foreach(println)
//=> -2147483648
希望对您有所帮助。