2013-08-15 31 views
28

map scala'daki 'un Exception arasındaki en temiz yolu nedir? Başarısız bir Geleceğin İstisnasını Eşleştirme

Ben De ki: Gelecek 1 ile başarılı

import scala.concurrent._ 
import scala.concurrent.ExecutionContext.Implicits.global 

val f = Future { 
    if(math.random < 0.5) 1 else throw new Exception("Oh no") 
} 

, ben o ben farklı Exception için Exception değiştirmek istiyorum başarısız ancak eğer tutmak istiyorum.

Ben dönüşümü olmaktadır birlikte gelen en iyi, ancak başarı durumu için gereksiz bir işlevi yapmak için beni gerektirir:

val f2 = f.transform(s => s, cause => new Exception("Something went wrong", cause)) 

hiçbir mapFailure(PartialFunction[Throwable,Throwable]) yoktur bir nedeni var mı?

+7

dönüşümü doğru yoldur. s => işlevini oluşturmanıza gerek yoktur, sadece "kimlik" –

+0

Şerefe. Ben 'kimlik' işlevini bilmiyordum. Eminim ki bu işe yaramayacak daha fazla zaman olacaktır. – theon

cevap

26

:

f recover { case cause => throw new Exception("Something went wrong", cause) } 

Scala 2.12 beri yapabilirsiniz:

f transform { 
    case s @ Success(_) => s 
    case Failure(cause) => Failure(new Exception("Something went wrong", cause)) 
} 

veya

f transform { _.transform(Success(_), cause => Failure(new Exception("Something went wrong", cause)))} 
+1

Bu çok net bir sözdizim olsa da, 'Throwable'ı' Throwable'a eşlemek yerine yeni bir istisna atmamız gerekiyor. Sadece bunun için bir birleştirici var mı? – owensmartin

+0

@owensmartin Güncellenmiş yanıtımı görün. :) –

13

Bunu aşağıdaki gibi recoverWith deneyebilirsiniz: Orada da

f recoverWith{ 
    case ex:Exception => Future.failed(new Exception("foo", ex)) 
} 
+0

Future.failed bir ExeecutionContext üzerinde değerlendirilmez: http://www.scala-lang.org/api/current/#scala.concurrent.Future$ bkz. '' Başarısız '' –

+0

@ViktorKlang, sonra kafam karışmış olmalı. Bu varsayımı, 'impl.KeptPromise' sınıfı 'onComplete' yöntemine bakarak yapmıştım. Orada iki satır var val readyEC = executor.prepare; (yeni CallbackRunnable (hazırladımEC, func)). executeWithValue (completedAs) '. Bunu, bir sebepten dolayı, hala bir sebepten ötürü çalıştırıcıya isabet ettiğine dair açık bir değer veriyor olsak bile, bunu ima ettim. Benim için her zaman garip görünüyordu ve sanırım aslında yanlış yorumluyordum. Başların için teşekkürler. – cmbaxter

+0

Cevaplar için teşekkürler. 'Kurtar'/'recoverWith' kullanarak tek tereddüt ettiğimde, hemen gördüğümde niyetin başarılı bir sonuçla başarısızlıktan kurtulmak olduğunu sanıyorum. Belki bu sadece benimdir. Öyle bile olsa iyi alternatifler, teşekkürler! – theon