2012-01-06 18 views
48

मैं एक सूत्र में एक अपवाद को पकड़ने के लिए है और यह मुख्य थ्रेड में फिर से बढ़ा कोशिश कर रहा हूँ की रक्षा:फिर से उठाते हैं और स्टैक ट्रेस

import threading 
import sys 

class FailingThread(threading.Thread): 
    def run(self): 
     try: 
      raise ValueError('x') 
     except ValueError: 
      self.exc_info = sys.exc_info() 

failingThread = FailingThread() 
failingThread.start() 
failingThread.join() 

print failingThread.exc_info 
raise failingThread.exc_info[1] 

यह मूलतः काम करता है और निम्नलिखित उत्पादन पैदावार:

(<type 'exceptions.ValueError'>, ValueError('x',), <traceback object at 0x1004cc320>) 
Traceback (most recent call last): 
    File "test.py", line 16, in <module> 
    raise failingThread.exc_info[1] 

हालांकि, अपवाद का स्रोत लाइन 16 पर इंगित करता है, जहां पुन: उठाया गया था।

Traceback (most recent call last): 
    File "test.py", line 7, in <module> 
+0

भयानक, मैं दिया भी फिर से ऊपर उठाने की है अन्य धागे से अपवाद हैं, लेकिन आप में से –

+0

संभव डुप्लिकेट :) करना चाहते हैं कभी नहीं चला गया जहाँ तक [पाइथन में "आंतरिक अपवाद" (ट्रेसबैक के साथ)? (Http://stackoverflow.com/questions/1350671/inner-exception-with-traceback-in-python) –

उत्तर

50

आप को बढ़ाने के लिए सभी तीन तर्कों का उपयोग करने की आवश्यकता है।

help('raise') से:

एक तिहाई वस्तु मौजूद न हो और न None, यह होना चाहिए ट्रैसबैक वस्तु (अनुभाग मानक प्रकार पदानुक्रम देखें), और यह वर्तमान के बजाय एवजी है उस स्थान के रूप में स्थान जहां अपवाद हुआ। यदि तीसरा ऑब्जेक्ट मौजूद है और ट्रेसबैक ऑब्जेक्ट या None नहीं है, तो TypeError अपवाद उठाया गया है। raise की तीन अभिव्यक्ति प्रपत्र खंड को छोड़कर एक में पारदर्शी ढंग से एक अपवाद फिर से बढ़ाने के लिए उपयोगी है, लेकिन raise कोई भाव के साथ यदि अपवाद को फिर से उठाया जा करने के लिए सबसे वर्तमान में हाल ही में सक्रिय अपवाद था प्राथमिकता दी जानी चाहिए गुंजाइश।

इस विशेष मामले में आप कोई अभिव्यक्ति संस्करण का उपयोग नहीं कर सकते हैं।

+3

नोट: यह पायथन 3 में काम नहीं करता है। –

+4

@ एंडीहेडन वास्तव में, पायथन 3 [raise] में (http://docs.python.org/3/reference/simple_stmts.html#the-raise-statement) को किसी भी तरह से कॉल करना होगा जैसे 'विफल करना थ्रेड.एक्ससी_इन्फो [0] ] (failingThread.exc_info [1])। with_traceback (failin gThread.exc_info [2]) '। यद्यपि पायथन 3 में 'संग्रहित_एक्सप्शन' से 'एवररर' बढ़ाएं, एक बेहतर आउटपुट –

+0

सुधार प्रदान कर सकता है, पहला व्यक्ति 'इस टिप्पणी के अनुसार' विफल होना चाहिए। थ्रेड.एक्ससी_इन्फो [1] .with_traceback (failingThread.exc_info [2]) 'इस टिप्पणी के अनुसार] (http://stackoverflow.com/questions/18188563/how-to-re-raise-an-exception-in-nested-try-except-blocks/18188660?noredirect=1#comment26654548_18188660) –

0

आप यह कुछ हद तक लिखा जा सका इस तरह::

try: 
    raise ValueError('x') 
except ValueError as ex: 
    self.exc_info = ex 

और उसके बाद का उपयोग मूल अपवाद लाइन 7. मैं कैसे इतना है कि उत्पादन पढ़ता मुख्य धागा संशोधित करने की क्या ज़रूरत है से आता है अपवाद से stacktrace?

raise failingThread.exc_info[0], failingThread.exc_info[1], failingThread.exc_info[2] 

के रूप में तीसरा तर्क ढेर को बरकरार रखता है में ट्रैस बैक वस्तु गुजर:

1

यह कोड स्निपेट दोनों अजगर 2 & 3 में काम करता है:

 1 try: 
----> 2  raise KeyError('Default key error message') 
     3 except KeyError as e: 
     4  e.args = ('Custom message when get re-raised',) #The comma is not a typo, it's there to indicate that we're replacing the tuple that e.args pointing to with another tuple that contain the custom message. 
     5  raise 
+0

डाउनवोट क्यों? – pkoch

+1

मैं अनुमान लगा सकता हूं कि डाउनवोट क्यों। यह समाधान केवल तभी वैध है जब कोई अपवाद हैंडलिंग नहीं था। कल्पना करें कि अपवाद को पकड़ने पर आप डीबी में स्थिति अपडेट करने का प्रयास करते हैं और यह भी विफल रहता है। उस मामले में अपवाद जो उठाया जाएगा वह अंतिम है (डीबी लेनदेन विफल) और जिसे हमने शुरू में पकड़ा नहीं था। – odedfos

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