Как обработать необработанное исключение бросить в monix onErrorHandle

Я использую задачи Monix, и я пытаюсь поймать Throwable, а затем преобразовать в пользовательскую ошибку. Я удалил / изменил код, чтобы он был простым и актуальным. Это код (вопрос следует за фрагментом кода):

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(... не возвращается. Вместо этого метод, который вызывает метод-обработчик, выдает ошибку. Как мне сделать это вернуть 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 значение отбрасывалось в задаче сбоя.

1 ответ

Решение

Несколько проблем с вашим образцом.

Для одного этот код не действителен Scala:

val localPackage = for {
  failfast <- 1 / 0
} yield failfast

Я думаю, ты имел в виду Task.eval(1 / 0),

Также onErrorHandle не имеет Task как тип возврата, вы, вероятно, думали о 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

Надеюсь это поможет.

Другие вопросы по тегам