2017-11-19 29 views
0

Monixタスクを使用していますが、Throwableをキャッチしてカスタムエラーに変換しようとしています。私はシンプルで関連性のあるコードを削除/変更しました。これは、(質問はコードスニペットの後に以下の)コードです:未処理の例外を処理する方法monix onErrorHandle

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) => ??? 
     } 
    } 
} 

私はprint文を見ることができていますが、予想Task.now(Response(...が返されていません。代わりに、ハンドラメソッドを呼び出すメソッドがエラーをスローしています。 Task[Response]を返品するにはどうすればよいですか?

成功例が機能し、失敗例は機能しません。

編集#1:スカラーコードでエラーを修正します。

編集#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の値がどのように失敗タスクで破棄されているのか理解していました。

答えて

2

サンプルにいくつか問題があります。私はあなたがTask.eval(1/0)を意味推測

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

が1の場合、このコードはScalaの有効ではありません。

またonErrorHandleには戻り値の型がTaskではありません。あなたはおそらくonErrorHandleWithを考えていました。部分的な関数(つまり、エラーのために例外をスローできる関数)を与えることは非常に悪い考えです。エラーにマッチさせる場合は、部分的な関数を引数として取るより良い代替方法はonErrorRecoveronErrorRecoverWithです。

ので、ここでのサンプルです:

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 

は、この情報がお役に立てば幸いです。