एरर होना आम बात है। Elixir में लोग अक्सर कहते हैं कि "अपने प्रोग्राम को क्रैश होने दें", लेकिन कई बार हमें फंक्शन कॉल को सँभालकर एक ज्ञात, ठीक स्थिति में वापस लाना पड़ता है, ताकि सॉफ्टवेयर का करार पूरा हो सके। कुछ भाषाओं में एरर का इस्तेमाल प्रोग्राम के फ्लो को नियंत्रित करने के लिए किया जाता है, लेकिन Elixir में ऐसा करने की सलाह नहीं दी जाती। जो फंक्शन एरर दे सकते हैं, उन्हें अक्सर सिर्फ नाम देखकर ही पहचाना जा सकता है: एरर देने वाले फंक्शन के नाम के अंत में ! लगा होता है। इसकी तुलना उन फंक्शन से कीजिए जो {:ok, value} या :error लौटाते हैं। लाइब्रेरी के इन उदाहरणों को देखिए:
Map.fetch(%{a: 1}, :b)
# => :error
Map.fetch!(%{a: 1}, :b)
# => raises KeyError
Elixir में एरर से बचने के लिए try .. rescue नाम का एक तरीका मौजूद है।
try do
raise RuntimeError, "error"
rescue
e in RuntimeError -> :error
end
चलिए इस तरीके को समझते हैं:
try से की जाती है।raise/2 को कॉल कर रहे हैं।rescue वाले हिस्से में हम जो एरर आई है, उसके मॉड्यूल नाम पर पैटर्न मैच करते हैं
-> के बाईं ओर:
e को एरर स्ट्रक्चर से मैच किया जाता है।in एक कीवर्ड है।RuntimeError वह एरर है जिससे हम बचना चाहते हैं।
_ इस्तेमाल कर सकते हैं, या in कीवर्ड को पूरी तरह हटा सकते हैं।इस तरीके से आप जिन एरर से बचते हैं, वे स्ट्रक्चर होते हैं (कभी-कभी इन्हें "एक्सेप्शन" भी कहा जाता है)। Elixir में एरर से बचने का काम बहुत कम किया जाता है। आम तौर पर जिस एरर से बचा गया है, उसे लॉग किया जाता है या किसी बाहरी मॉनिटरिंग सर्विस को भेजा जाता है, और फिर वही एरर दोबारा दी जाती है। इसका मतलब है कि आम तौर पर हमें किसी खास एरर स्ट्रक्चर के अंदरूनी ढाँचे की परवाह नहीं करनी पड़ती।
इस एक्सेप्शन कॉन्सेप्ट में आप एरर स्ट्रक्चर के बारे में और जानेंगे, जिसमें अपनी खुद की कस्टम एरर बनाने का तरीका भी शामिल है।
आप Instruments of Texas में काम करते हैं और आपको Elixir में लिखे एक प्रायोगिक रिवर्स पोलिश नोटेशन [RPN] कैलकुलेटर पर काम करना है। आपकी टीम को एक समस्या का सामना करना पड़ रहा है: कुछ ऑपरेशन एरर देते हैं और इससे पूरी प्रक्रिया क्रैश हो जाती है। आपको एक फंक्शन लिखना है जो ऑपरेशन फंक्शन को लपेट ले, ताकि एररों को Elixir की शैली के कोड से और बेहतर ढंग से संभाला जा सके।
ऐसा फंक्शन calculate!/2 बनाइए जो ऑपरेशन फंक्शन को कॉल करे और उसे एकमात्र आर्गुमेंट के रूप में स्टैक दे। ऑपरेशन फंक्शन कहीं और बनाया गया है, लेकिन आप जानते हैं कि यह या तो सफलतापूर्वक पूरा हो सकता है या एरर दे सकता है।
stack = []
operation = fn _ -> :ok end
RPNCalculator.calculate!(stack, operation)
# => :ok
stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate!(stack, operation)
# => ** (ArgumentError) An error occurred
जिस फंक्शन के नाम के अंत में
!होता है, वह प्रोग्रामर के लिए चेतावनी है कि यह फंक्शन एरर दे सकता है
आगे और खोज करने पर आप देखते हैं कि कई फंक्शन अपनी सफलता या विफलता बताने के लिए एटम और टपल का उपयोग करते हैं। इसी तरीके से calculate/2 बनाइए।
stack = []
operation = fn _ -> "operation completed" end
RPNCalculator.calculate(stack, operation)
# => {:ok, "operation completed"}
stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate(stack, operation)
# => :error
कुछ एररों में ऐसी ज़रूरी जानकारी होती है जो आपके साथ काम करने वालों के पास होनी चाहिए, ताकि सिस्टम ठीक से काम करता रहे। एरर का संदेश आगे भेजने के लिए calculate_verbose/2 बनाइए। एरर एक स्ट्रक्ट है, जिसमें :message फील्ड होता है।
stack = []
operation = fn _ -> "operation completed" end
RPNCalculator.calculate_verbose(stack, operation)
# => {:ok, "operation completed"}
stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate_verbose(stack, operation)
# => {:error, "An error occurred"}
Exercism पर साइन अप कीजिए और Elixir को 58 कॉन्सेप्ट168 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।