2016-10-06 6 views
7

में वापस कर दिया गया है यदि भविष्य में एक असफल अपवाद लौटाता है तो मैं कैसे संभाल सकता हूं?जारी रखें जब एक Future.failed (नया अपवाद ("")) स्कैला

परिदृश्य है कि मेरे कोड कॉल getValue(), verifyValue() लिए परिणाम नक्शे और उसके बाद मैं इस मामले में जहां getValue का परिणाम() Future.failed(new Exception("message")) है संभाल करने में सक्षम होना चाहते है। हालांकि जब मैं इसे चलाता हूं, तो getValue() का नतीजा एक असफल भविष्य है, तो यह इसे संभालने के बजाय अपवाद फेंकता है।

क्या किसी के पास कोई सुझाव है कि मैं यह कैसे करूं?

def method(): Future[JsObject] = { 
    getValue().flatMap(verifyValue(_)) 
} 

def getValue(): Future[JsObject] = { 
    try { 
     value1 <- getValue1() 
     value2 <- getValue2(value1) 
    } yield { 
     value2 
    } 
} 

def verifyValue(result: Any): Future[JsObject] = { 
    result match { 
    case e: Exception => 
     getValue() 
    case json: JsObject => Future.successful(json) 
    } 
} 

अद्यतन: मुझे लगता है मैं मूल प्रश्न के साथ इस स्पष्ट कर दिया नहीं लगता है, लेकिन कारण है कि मैं मूल्य flatmap है जिन्हें मैंने स्पष्ट रूप में वायदा में से किसी के लिए प्रतीक्षा करने के लिए नहीं करना चाहते हैं मेरा कोड, और इसलिए मैं मूल्य को हल करने के लिए Future.onComplete {} का उपयोग नहीं करना चाहता हूं।

अद्यतन 2: एक और चीज जो स्पष्ट नहीं हो सकती है कि अगर यह अपवाद फेंकता है, तो मैं एक और विधि कॉल करना चाहता हूं। मैं नहीं चाहता कि यह केवल अपवाद को संभालने के लिए है, यह अपवाद लॉग करने जा रहा है और फिर दूसरी विधि को कॉल करें जिसका रिटर्न वैल्यू getValue() के समान प्रकार का है।

उत्तर

3

क्या मैं कर रहा Future.fallbackTo() विधि का उपयोग कर रहा समाप्त हो गया के भविष्य लेता है।

def method(): Future[JsObject] = { 
    getValue().fallbackTo(method1()).fallbackTo(method2()).fallbackTo(method3()) 
} 

पहले getValue() से भविष्य में विफल रहता है, तो यह method1() कॉल करेंगे। यदि यह भी विफल रहता है, तो यह method2() इत्यादि को कॉल करेगा। यदि कोई विधि सफल हो जाती है, तो वह उस मान को वापस कर देगी। यदि कोई भी विधि सफल नहीं होती है, तो यह असफल भविष्य को getValue() से वापस कर देगा।

यह समाधान आदर्श नहीं है, क्योंकि अगर सभी प्रयास विफल हो जाते हैं तो मैं सभी चार अपवादों को फेंकना चाहता हूं, लेकिन कम से कम मुझे getValue() विधि को फिर से प्रयास करने की अनुमति मिलती है।

+1

लगता है जैसे आप चाहते हैं http://johnkurkowski.com/posts/accumulating-multiple-failures-in-a-ValidationNEL/ – Yawar

+0

यह आश्चर्यजनक लगता है! – annedroiid

+0

धन्यवाद, लेकिन मैं एक उदार-योग्य उत्तर टाइप करने के लिए बहुत आलसी हूं, और पोस्ट अवधारणाओं को समझाते हुए एक बहुत अच्छा काम करता है :-) – Yawar

1
import scala.util.{Success, Failure} 

f.onComplete { 
    case Success(value) => // do sth with value 
    case Failure(error) => // do sth with error 
} 

आप) अपने विधि (में onComplete उपयोग कर सकते हैं, अन्य विकल्पों के लिए नीचे दिए गए लिंक के रूप में अच्छी तरह से देखें:

http://www.scala-lang.org/api/2.9.3/scala/concurrent/Future.html

6

उपयोग recover या recoverWith

की वसूली या recoverWith जब भविष्य कहा जाता है एक अपवाद के साथ विफल रहता है। पुनर्प्राप्ति ब्लॉक में आप वैकल्पिक मूल्य दे सकते हैं।

recoverWithrecover के विपरीत कुछ

getValue().recover { case th => 
    //based on the exception type do something here 
    defaultValue //returning some default value on failure 
} 
+0

यदि मैं ऐसा करने का प्रयास करता हूं, तो getValue2 (value1) में "मिस्चैच टाइप करें, अपेक्षित: स्ट्रिंग, वास्तविक: ऑब्जेक्ट" की एक संकलन त्रुटि है, भले ही वसूली में मैं केवल getValue() को कॉल करता हूं। – annedroiid

+0

कृपया इसे ऊपर उठाना बंद करें। यह काम नहीं करता है, पुनर्प्राप्त और पुनर्प्राप्त करता है विधियों के साथ केवल अपवाद को संभालता है, आप किसी अन्य विधि को कॉल नहीं कर सकते जो सफल मूल्य के साथ वापस आ सकता है, जो मेरा उद्देश्य है। – annedroiid

+0

@annedरोइड - क्या आप अपने प्रश्न में, कम से कम सभी प्रासंगिक तरीकों के प्रकार हस्ताक्षर, और आपको प्राप्त होने वाले सटीक त्रुटि संदेश पोस्ट कर सकते हैं? बीटीडब्ल्यू, 'रिकवरी' और 'रिकवरी विथ' काफी स्पष्ट रूप से आप एक सफल मूल्य की गणना और वापसी करते हैं। Http://www.scala-lang.org/api/current/index.html#scala.concurrent देखें।भविष्य @ पुनर्प्राप्ति [यू>: टी] (पीएफ: आंशिक समारोह [थ्रोबल, यू]) (implicitexecutor: scala.concurrent.ExecutionContext): scala.concurrent.Future [U] – Yawar

संबंधित मुद्दे