[SCALA] 어떻게 스칼라 미래에 던져 예외를 잡아합니까?
SCALA어떻게 스칼라 미래에 던져 예외를 잡아합니까?
나는 시간 제한이있는 블록을 실행하기위한 것입니다 거기 표준 스칼라 함수를 내 대답을 일한지? 예외가 미래에 던져진다면 문제로 실행했다.
def runWithTimeout[T](timeoutMs: Long)(f: => T) : Option[T] = {
awaitAll(timeoutMs, future(f)).head.asInstanceOf[Option[T]]
}
그래서
runWithTimeout(50) { "result" } should equal (Some("result"))
runWithTimeout(50) { Thread.sleep(100); "result" } should equal (None)
하지만 그것은 누설하지 않습니다 내 블록에서 예외가 발생하지만 섭취 한 경우 - 다음은 "..no 예외가 발생했다"실패 그래서
intercept[Exception] {
runWithTimeout(50) { throw new Exception("deliberate") }
}.getMessage should equal("deliberate")
시스템 오류 메시지와 스택 추적을 가지고
<function0>: caught java.lang.Exception: deliberate
어디에서 인쇄 된 스칼라 런타임하지만 난 찾을 수 없습니다.
별도로 발생하는 경우 예외 전파를 잡아 다른 블록에서 포장 F에서 던져 awaitAll 및 / 또는 미래를 설득 할 수있는 방법은 무엇입니까?
해결법
-
==============================
1.짧은 답변 : 아니오.
짧은 답변 : 아니오.
당신이 스레드 환경에서 작업 할 때 발신자의 예외에 대해 알고 싶어하기 때문에 예외가, 당신이 원하는 것을하지 않고, 예외가 미래의 스레드에서 발생합니다.
당신은 예외가 무엇인지 알고 싶다면 대신, 당신은 어느 반환해야합니다 [예외, WhatYouWant] - 물론, 당신은 미래에서 그 예외를 잡아 그것을 포장해야합니다.
scala> scala.actors.Futures.future{ try { Right("fail".toInt) } catch { case e: Exception => Left(e) } } res0: scala.actors.Future[Product with Serializable with Either[Exception,Int]] = <function0> scala> res0() // Apply the future res1: Product with Serializable with Either[Exception,Int] = Left(java.lang.NumberFormatException: For input string: "fail")
-
==============================
2.면책 조항 : 형태 보증에 대한 I 작업
면책 조항 : 형태 보증에 대한 I 작업
아니면 .... 당신은 Akka를 사용할 수 있습니다 그리고 당신은 당신이 그것을 위해 농구를 통해 갈 필요없이 원하는 당신을 줄 것이다.
val f: Future[Int] = actor !!! message
그때
f.get
배우에서 일어난 예외가 발생합니다
f.await.exception
당신에게 옵션을 줄 것이다 [의 Throwable]
-
==============================
3.@Rex 커의 제안을 통해 내 방식대로 작업, 내가 만든
@Rex 커의 제안을 통해 내 방식대로 작업, 내가 만든
object Timeout { val timeoutException = new TimeoutException def runWithTimeout[T](timeoutMs: Long)(f: => T) : Either[Throwable, T] = { runWithTimeoutIgnoreExceptions(timeoutMs)(exceptionOrResult(f)) match { case Some(x) => x case None => Left(timeoutException) } } def runWithTimeout[T](timeoutMs: Long, default: T)(f: => T) : Either[Throwable, T] = { val defaultAsEither: Either[Throwable, T] = Right(default) runWithTimeoutIgnoreExceptions(timeoutMs, defaultAsEither)(exceptionOrResult(f)) } def runWithTimeoutIgnoreExceptions[T](timeoutMs: Long)(f: => T) : Option[T] = { awaitAll(timeoutMs, future(f)).head.asInstanceOf[Option[T]] } def runWithTimeoutIgnoreExceptions[T](timeoutMs: Long, default: T)(f: => T) : T = { runWithTimeoutIgnoreExceptions(timeoutMs)(f).getOrElse(default) } private def exceptionOrResult[T](f: => T): Either[Throwable, T] = try { Right(f) } catch { case x => Left(x) } }
그래서
@Test def test_exception { runWithTimeout(50) { "result" }.right.get should be ("result") runWithTimeout(50) { throw new Exception("deliberate") }.left.get.getMessage should be ("deliberate") runWithTimeout(50) { Thread.sleep(100); "result" }.left.get should be (Timeout.timeoutException) runWithTimeout(50, "no result") { "result" }.right.get should be ("result") runWithTimeout(50, "no result") { throw new Exception("deliberate") }.left.get.getMessage should be ("deliberate") runWithTimeout(50, "no result") { Thread.sleep(100); "result" }.right.get should be ("no result") }
다시 말하지만, 나는 스칼라 초보자의 비트를, 그래서 피드백을 환영합니다.
-
==============================
4.scala.concurrent.ops.future 예외 처리를 포함한다.
scala.concurrent.ops.future 예외 처리를 포함한다.
그래서, 대신 scala.actors.Futures.future, 수입 scala.concurrent.ops.future를 가져 오는 대신.
그 간단한 변화는 가져 오기에 발신자의 호출이 예외를 다시 발생하는 갔지 거기 발생할 수 있습니다. 그것은 잘 작동합니다!
-
==============================
5.또는 사용 Future.liftTryTry, 미래 [] 시도 [오브젝트]로 미래 [객체]에서 변합니다, 당신은 정상적으로 / 종료를 시도 [오브젝트]에 일치 예외 케이스 던져 (예)를 확인하고 로그인 할 수 있습니다
또는 사용 Future.liftTryTry, 미래 [] 시도 [오브젝트]로 미래 [객체]에서 변합니다, 당신은 정상적으로 / 종료를 시도 [오브젝트]에 일치 예외 케이스 던져 (예)를 확인하고 로그인 할 수 있습니다
-
==============================
6.당신은 캐치 예외 위해 방법 exceptionHandler를 오버라이드 (override) 할 필요가있다. 그래서 옵션은 exceptionHandler와 MyFutureActor을 만들어 귀하의 자신의 미래 방법을 정의하는 것입니다.
당신은 캐치 예외 위해 방법 exceptionHandler를 오버라이드 (override) 할 필요가있다. 그래서 옵션은 exceptionHandler와 MyFutureActor을 만들어 귀하의 자신의 미래 방법을 정의하는 것입니다.
편집 : 그것을 서브 클래스 화하는 것은 불가능하므로 FutureActor은 비공개입니다.
또 다른 옵션은 예외가 일어 났을 때 알고 링크를 사용하는 것입니다.
그러나, 나는 렉스 커의 접근 방식이 더 좋은 생각 - 그냥 예외를 잡을 것입니다 뭔가 기능을 래핑. 너무 나쁜 미래는 이미 그렇게하지 않습니다.
from https://stackoverflow.com/questions/6229778/how-do-i-get-hold-of-exceptions-thrown-in-a-scala-future by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 추출기 (추출기를 사용할 것이라고 또는 다른 곳) case 문의 몸에있는 매개 변수를 사용자 정의 할 수 있습니까? (0) | 2019.11.23 |
---|---|
[SCALA] "=> 외부"정말 무엇을 의미합니까? (0) | 2019.11.23 |
[SCALA] 스칼라에서 합성 클래스로 싱글 톤? (0) | 2019.11.23 |
[SCALA] 우편 번호에 여러 시퀀스 (0) | 2019.11.23 |
[SCALA] 슬라이스 배열 방법 및 열의 합 요소? (0) | 2019.11.23 |