2015-11-19 12 views
8

मैं उन कार्यों में आया हूं जो Future लौटाते हैं लेकिन तुरंत अपवाद भी फेंक देते हैं। इस तरह उदाहरण के लिए:क्या फ़ंक्शन [ए] फेंकने वाले अपवादों को फेंकना चाहिए?

def func(): Future[String] { 
    if (something) { 
    // this 
    Future.failed(new RuntimeException("test")) 
    } else { 
    // and this 
    throw new RuntimeException("test") 
    } 
} 

यह व्यवहार फोन करने वाले के लिए कष्टप्रद लगता है, क्योंकि आप दोनों त्रुटियों को पकड़ने के लिए कुछ इस तरह करना है:

try { 
    func() recover { 
    case e: Exception => handleError(e) 
    } 
} catch { 
    case e: Exception => Future.successful(handleError(e)) //or Future.failed etc 
} 

मैं देखा है कि खेलने के ढांचे में WSClient करता है यह (यूआरएल खराब होने पर अपवाद फेंक रहा है, और Future लौटा रहा है जो HTTP अनुरोध विफल होने पर विफल रहता है)।

क्या यह अच्छा अभ्यास है? क्या इस तरह व्यवहार करने वाले कार्यों से त्रुटियों को संभालने का कोई बेहतर तरीका है?

+0

नहीं, अपवादों का उपयोग करने के लिए यह अच्छा अभ्यास नहीं है - http://programmers.stackexchange.com/questions/223329/side-effects-breaking-referential-transparency। शायद 'भविष्य [या तो [ए, बी]] का उपयोग करके आप करेंगे - https://www.reddit.com/r/scala/comments/3r5ii6/on_handling_futureeithera_b_sequencing/। –

+0

@ केविन मैरिडिथ मैं अपेक्षित त्रुटियों के लिए 'या तो [ए, बी]' का उपयोग करके समझता हूं, यहां मेरी समस्या यह नहीं है कि उनको कैसे अंतर किया जाए, लेकिन क्या किसी फ़ंक्शन को अपवाद फेंकना चाहिए और अप्रत्याशित विफलता के लिए असफल वायदा वापस करना चाहिए (ऐसा लगता है कि उन्हें नहीं होना चाहिए)। –

उत्तर

4

Future का अंततः कुछ वापस करने के लिए उपयोग किया जाता है, लेकिन यह वास्तव में तब होता है जब यह वास्तव में होता है।

एक .NET परिप्रेक्ष्य से आ रहा है (हमारे पास Task है): यदि अनुरोध स्पष्ट रूप से अमान्य है (जैसे विकृत यूआरएल) तो एक अपवाद फेंक दिया जाना चाहिए। वास्तव में वेब अनुरोध करने से पहले आप इसे पहले ही जानते हैं, इसलिए अपवादों में देरी करने की कोई आवश्यकता नहीं है।

दूसरी तरफ, यदि सर्वर डाउन (टाइमआउट?) है या सर्वर कुछ ऐसा देता है जो आपका क्लाइंट समझ में नहीं आता है: यह बाद में संभाला जा सकता है और इसे बाद में संभाला जाना चाहिए, क्योंकि प्रतिक्रिया करते समय प्रतिक्रिया सीधे उपलब्ध नहीं होती है कॉल। प्रतिक्रिया उपलब्ध होने तक हम ब्लॉक करने में सक्षम होंगे, लेकिन यह Future बेकार प्रदान करेगा।

मुझे लगता है कि यह 'बाहर निकलें' प्रोग्रामिंग शैली के साथ सबसे अच्छी तुलना में है।

+4

यह स्कैला में वास्तव में बेवकूफ नहीं है- किसी भी पुनर्प्राप्ति योग्य त्रुटियों को भविष्य में विफल होना चाहिए, फेंक नहीं दिया जाना चाहिए, इससे कोई फर्क नहीं पड़ता कि वे कब होते हैं। –

+0

मुझे लगता है कि एक सही जवाब देगा। :) – Caramiriel

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

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