इनायत फाइल में त्रुटियों को कैसे इनायत करें


20

मैं अपनी इनिट फ़ाइल चलाते समय त्रुटियों को पकड़ने का एक तरीका चाहूंगा, और फिर उन्हें इनायत से संभालूंगा। मेरे अधिकांश महत्वपूर्ण अनुकूलन और कीबाइंडिंग मेरी इनिट फ़ाइल के अंत में दिखाते हैं कि यह सुनिश्चित करने के लिए कि अन्य सेटिंग्स उनके ऊपर लागू नहीं होती हैं। समस्या यह है कि जब इनिशियलाइज़ेशन जल्दी खत्म हो जाता है, तो मैं अपने परिचित कुंजी बाइंडिंग और सेटिंग्स लागू किए बिना समस्या को पूरी तरह से अपंग करने की कोशिश कर रहा हूं।

क्या कोई त्रुटि होने पर इनिशियलाइज़ेशन प्रक्रिया को समाप्त करने का कोई तरीका है?

जवाबों:


9

दो विकल्प, जिनमें से कोई भी सही नहीं है, दिमाग में आते हैं। सबसे पहले, आप अपने प्रारंभिक आरंभीकरण कोड (यानी, इससे पहले कि यह आपके अनुकूलन के लिए हो जाता है) में लपेट सकता है (ignore-errors ...)। वहाँ तो कर रहे हैं - त्रुटियों, तथापि, वहाँ प्रतिक्रिया का एक बहुत कुछ नहीं होगा ignore-errorsबस वापस आ जाएगी nil

एक अधिक जटिल विकल्प संभावित बग कोड को ( unwind-protectऔर शून्य पर सेट के with-demoted-errorsसाथ debug-on-error) के संयोजन में लपेटना होगा । उत्तरार्द्ध इनायत का सामना करेगा, जो पहली बार में सामने आएगी और *Messages*आपके निरीक्षण के लिए बफर को त्रुटि संदेश की सूचना देगा । इस बीच, unwind-protectशरीर के बाकी हिस्सों (संभवतः आपके अनुकूलन) का मूल्यांकन किया जाएगा। इसलिए, जैसे:

(unwind-protect
    (let ((debug-on-error nil))
      (with-demoted-errors
        (message "The world is about to end")
        (sleep-for 2)
        (/ 10 0)                        ; divide by zero signals an error
        (message "This will never evaluate")
        (sleep-for 2)
        (setq some-var 5)))
  (message "Here are the unwind forms that will always evaluate")
  (sleep-for 2)
  (setq some-var 10)
  (setq another-var "puppies")
  (message "All done!"))

1
अच्छा लगा, मैं नहीं था with-demoted-errors। आप इसमें एक स्ट्रिंग तर्क जोड़ सकते हैं "LOOK OVER HERE!!! %s", इसलिए आपको संदेशों के बफर में त्रुटि की संभावना कम है।
मालाबार

@ मलबारबा का यह रूप with-demoted-errorsकेवल 24.4 में उपलब्ध है
चंद्रग्रहण

@lunaryorn धन्यवाद, वह नहीं जानता था।
मालाबार

दरअसल, मैं जिस संस्करण पर हूं, वह 24.3.1 है।
दान

8

@ आप अच्छी तरह से वर्णन कर सकते हैं कि आप संदेशों में त्रुटियों को कैसे बदल सकते हैं। आप त्रुटियों का उपयोग करके जो चाहें कर सकते हैं condition-case। फिर भी एक अन्य विकल्प का उपयोग करना है unwind-protect

मैं condition-caseयहाँ पर बिना किसी कारण के रहूँगा ।

त्रुटि पकड़ना

इस बात की हमेशा गारंटी होनी चाहिए कि आपकी मुख्य परिभाषा का मूल्यांकन किया जाए, चाहे जो कुछ भी हुआ हो condition-case। कोई भी त्रुटि अंदर जमा हो जाती है init-error

(defvar init-error nil 
  "The error which happened.")

(condition-case the-error
    (progn
      ;; Do the dangerous stuff here.
      (require 'what-I-want))
  (error
   ;; This is only evaluated if there's an error.
   (setq init-error the-error)))

;;; Do the safe stuff here.
(define-key uncrippling-map "\C-h" 'help!)

इसे वापस फेंकना

बाद में, बस फिर से त्रुटि फेंक दें। ऐसे कई तरीके हैं जिनसे आप यहाँ कर सकते हैं।

;;; Throw the error again here.
(when init-error
  (funcall #'signal (car init-error) (cdr init-error)))

unwind-protectत्रुटि को तुरंत फिर से उठाया जाता है, इसके बचाव खंड में जो भी कोड डालते हैं उसे निष्पादित करने के बाद। यह finallyजावा जैसी भाषा में है, बजाय catch
पवित्रता

2

अन्य जवाबों ने निम्न स्तर की त्रुटि से निपटने की सुविधाओं को अच्छी तरह से कवर किया है जो इस तरह से एक मामले में उपयोगी होंगे। एक और तरीका जो मदद कर सकता है वह है मॉड्यूलरिटी। उदाहरण के लिए, मैंने अपनी इनिशियलाइज़ेशन फ़ाइल को कई अलग-अलग फाइलों में विभाजित किया है ( provideउपयुक्त के रूप में उपयोग करके ), और मैं उन्हें इस फ़ंक्शन के बजाय इसका उपयोग करके लोड करता हूं require:

(defun my/require-softly (feature &optional filename)
  "As `require', but instead of an error just print a message.

If there is an error, its message will be included in the message
printed.

Like `require', the return value will be FEATURE if the load was
successful (or unnecessary) and nil if not."
  (condition-case err
      (require feature filename) 
    (error (message "Error loading %s: \"%s\""
                    (if filename (format "%s (%s)" feature filename) feature)
                    (error-message-string err))
           nil)))

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

बेशक, यह फ़ंक्शन वास्तव requireमें कॉल को अलग करने से अलग नहीं है with-demoted-errors(मैंने इसके बारे में जानने से पहले इसे लिखा था with-demoted-errors), लेकिन महत्वपूर्ण बिंदु यह है कि आप अनिवार्य रूप से डैन के संयोजन with-demoted-errorsऔर unwind-protectरैपिंग के बिना (संभवतः बहुत लंबा) जैसे कुछ को लागू कर सकते हैं कोड के ब्लॉक।


यह समारोह ठीक वैसा ही था जैसा मैं था। एक त्रुटि की रिपोर्ट करने के बावजूद मेरे एमएसीएस अब बूट करते हैं। उसके बाद, मैं सिर्फ अपनी इनिट फ़ाइल और लोड करता हूं eval-buffer। इसे पोस्ट करने के लिए धन्यवाद।
केविन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.