how to catch an exception inside a scala future' s callback onCompelete Success case?

292 Views Asked by At

I have a future and sending that value to the caller actor my problem is I am calling future.onCompelete and inside its case Success callback I am getting an exception I want to know what is the right way to catch that exception as the Failure block will not work in this use case here is my code

val future = Futute{calling a http route which sends back a response}
future.onComplete {
case Success (response) => //do some processing with response got some exception while doing this 
throw new RunTimeException("got exception while working the response")
sender() ! response
case Failure (ex) =>  ex.printStackTrace
}

in the above code, I am unable to catch the exception I only got AskTimeOutException when i am calling this future code I can only catch the exception if I surround it with try-catch like this

val future = Futute{calling a http route which sends back a response}
    future.onComplete {
    case Success (response) => //do some processing with response got some exception while doing this 
try {    
throw new RunTimeException("got exception while working the response")
    sender() ! response
    }
    catch {
     case ex:Exception(e)=>log.error("got an exception",ex)
     }
case Failure (ex) =>  ex.printStackTrace
    }

is this the right approach to do this? or is there any better way to do this?

1

There are 1 best solutions below

0
Levi Ramsey On

In general, onComplete shouldn't be used if you care about an exception thrown in the callback (nor should the other Unit-returning method which needs an (implicit) ExecutionContext: foreach).

The most general approach and the most similar to onComplete is to use transform (or its cousin transformWith: transform is to transformWith as map is to flatMap), for example

future.transform {
  case Success(response) =>
    // these are both equivalent... the exception will get wrapped into a failed future
    Failure(new RuntimeException("BOOM!"))
    throw new RuntimeException("BOOM!")

  case f @ Failure(ex) =>
    ex.printStackTrace()
    f  // pass-through
}