अजगर अपवाद संदेश कैप्चरिंग


519
import ftplib
import urllib2
import os
import logging
logger = logging.getLogger('ftpuploader')
hdlr = logging.FileHandler('ftplog.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
FTPADDR = "some ftp address"

def upload_to_ftp(con, filepath):
    try:
        f = open(filepath,'rb')                # file to send
        con.storbinary('STOR '+ filepath, f)         # Send the file
        f.close()                                # Close file and FTP
        logger.info('File successfully uploaded to '+ FTPADDR)
    except, e:
        logger.error('Failed to upload to ftp: '+ str(e))

यह काम नहीं करता है, मुझे सिंटैक्स त्रुटि मिलती है, किसी फ़ाइल में सभी प्रकार के अपवादों को लॉग करने के लिए यह करने का उचित तरीका क्या है


2
तुम्हारा इंडेंटेशन टूट गया है। और उसके ,बाद छोड़ देना except
स्वेन मार्नाच

3
@SvenMarnach, यदि आप के ,बाद छोड़ देते हैं except, तो आपको मिलेगा global name 'e' is not defined, जो गलत सिंटैक्स से बेहतर नहीं है।
वैल

12
@ वेल: पायथन संस्करण के आधार पर होना चाहिए except Exception as eया except Exception, e
स्वेन मार्नाच

1
संभवतः यह उन 8 उत्तरों के आसपास है, लेकिन जब आप एक फ़ाइल खोलते हैं, तो करीब का हिस्सा कभी भी कोशिश के बयान के अंदर नहीं होना चाहिए, लेकिन या तो अंत में बयान या एक बयान के साथ लिपटे।
जेसी रोक्मोंडे

जवाबों:


732

आपको यह परिभाषित करना होगा कि आप किस प्रकार के अपवाद को पकड़ना चाहते हैं। इसलिए एक सामान्य अपवाद except Exception, e:के except, e:लिए लिखें (जो कि वैसे भी लॉग किया जाएगा)।

अन्य संभावना यह है कि अपनी पूरी कोशिश / इस तरह कोड को छोड़कर लिखें:

try:
    with open(filepath,'rb') as f:
        con.storbinary('STOR '+ filepath, f)
    logger.info('File successfully uploaded to '+ FTPADDR)
except Exception, e: # work on python 2.x
    logger.error('Failed to upload to ftp: '+ str(e))

पायथन में 3.x और पायथन के आधुनिक संस्करणों में 2.x का उपयोग किया except Exception as eजाता है except Exception, e:

try:
    with open(filepath,'rb') as f:
        con.storbinary('STOR '+ filepath, f)
    logger.info('File successfully uploaded to '+ FTPADDR)
except Exception as e: # work on python 3.x
    logger.error('Failed to upload to ftp: '+ str(e))

118
repr (e) आपको अपवाद देता है (और संदेश स्ट्रिंग); str (e) केवल संदेश स्ट्रिंग देता है।
व्हाइटबर्ड

11
लॉगिंग अपवाद के विकल्प के रूप में आप logger.exception(e)इसके बजाय उपयोग कर सकते हैं । यह एक ही logging.ERRORस्तर पर ट्रेसबैक के साथ अपवाद को लॉग करेगा ।
mbdevpl

1
@mbdevpl यह सच नहीं लगता। यह अपवाद पर str () कॉल करने के लिए प्रतीत होता है: ideone.com/OaCOpO
KevinOrr

6
except Exception, e:अजगर में मेरे लिए एक सिंटैक्स त्रुटि फेंकता है 3. क्या यह अपेक्षित है?
चार्ली पार्कर

27
@CharlieParker Python3 में लिखते हैंexcept Exception as e:
eumiro

281

वाक्यविन्यास अब अजगर में समर्थित नहीं है। इसके बजाय निम्नलिखित का उपयोग करें।

try:
    do_something()
except BaseException as e:
    logger.error('Failed to do something: ' + str(e))

2
वास्तव में, आपको logger.error ('कुछ करने में विफल:% s', str (e)) का उपयोग करना चाहिए, यदि आपका लकड़हारा स्तर त्रुटि से ऊपर है तो यह स्ट्रिंग प्रक्षेप नहीं करता है।
avyfain

7
@avyfain - आप गलत हैं। बयान logging.error('foo %s', str(e))हमेशा eएक स्ट्रिंग में बदल जाएगा । यह हासिल करने के लिए कि आप क्या उपयोग कर रहे हैं logging.error('foo %s', e)- जिससे लॉगिंग फ्रेमवर्क रूपांतरण को करने (या न करने) की अनुमति देता है।
रॉन डाहलग्रेन

1
आप एक अजगर REPL (यहाँ Python 3.5.2 और ipython के साथ) में सत्यापित कर सकते हैं: मेरे जिस्म को यहाँ देखें
Ron Dahlgren

2
लॉगिंग अपवाद के विकल्प के रूप में आप logger.exception(e)इसके बजाय उपयोग कर सकते हैं । यह एक ही logging.ERRORस्तर पर ट्रेसबैक के साथ अपवाद को लॉग करेगा ।
mbdevpl

11
सावधान रहें except BaseExceptionऔर except Exceptionसमान स्तर पर नहीं हैं। except ExceptionPython3 में काम करता है, लेकिन यह KeyboardInterruptउदाहरण के लिए नहीं पकड़ा जाएगा (जो आपके कोड को बाधित करने में सक्षम होने के लिए बहुत सुविधाजनक हो सकता है!), जबकि BaseExceptionकोई अपवाद पकड़ता है। अपवादों के पदानुक्रम के लिए इस लिंक को देखें ।
जीनज

41

लकड़हारे के लिए कुछ सरल करने के लिए इसे अद्यतन करना (अजगर 2 और 3 दोनों के लिए काम करता है)। आपको ट्रेसबैक मॉड्यूल की आवश्यकता नहीं है।

import logging

logger = logging.Logger('catch_all')

def catchEverythingInLog():
    try:
        ... do something ...
    except Exception as e:
        logger.error(e, exc_info=True)
        ... exception handling ...

यह अब पुराना तरीका है (हालांकि अभी भी काम करता है):

import sys, traceback

def catchEverything():
    try:
        ... some operation(s) ...
    except:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        ... exception handling ...

exc_value त्रुटि संदेश है।


2
यह मेरी पसंदीदा विधि होगी। बस स्ट्रिंग को प्रिंट करना मुझे लगता है कि लॉगिंग के लिए उपयोगी है, लेकिन अगर मुझे उस जानकारी के साथ कुछ भी करने की आवश्यकता है, तो मुझे केवल एक स्ट्रिंग से अधिक की आवश्यकता है।
सुलीमेश

3
आपको दूसरे उदाहरण में, 'ट्रेसबैक' आयात करने की आवश्यकता नहीं है?
स्टारकॉफ

35

कुछ ऐसे मामले हैं जहां आप e.message या e.messages का उपयोग कर सकते हैं .. लेकिन यह सभी मामलों में काम नहीं करता है। वैसे भी अधिक सुरक्षित str (e) का उपयोग करना है

try:
  ...
except Exception as e:
  print(e.message)

42
इस के साथ समस्या यह, उदाहरण के लिए, अगर आप except Exception as e, और eएक है IOError, आप प्राप्त e.errno, e.filename, और e.strerror, लेकिन जाहिरा तौर पर कोई e.message(पायथन में कम से कम 2.7.12)। यदि आप त्रुटि संदेश पर कब्जा करना चाहते हैं str(e), तो अन्य उत्तरों की तरह उपयोग करें ।
एपीएलएम

@epalm यदि आप अपवाद से पहले IOError को पकड़ लेते हैं तो क्या होगा?
अल्बर्ट थॉम्पसन

@ HeribertoJuárez विशेष मामलों को क्यों पकड़ें जबकि आप इसे केवल स्ट्रिंग में डाल सकते हैं?
होससेएनजेएफ

25

यदि आप त्रुटि वर्ग, त्रुटि संदेश और स्टैक ट्रेस (या उनमें से कुछ) चाहते हैं, तो उपयोग करें sys.exec_info()

कुछ स्वरूपण के साथ न्यूनतम काम कोड:

import sys
import traceback

try:
    ans = 1/0
except BaseException as ex:
    # Get current system exception
    ex_type, ex_value, ex_traceback = sys.exc_info()

    # Extract unformatter stack traces as tuples
    trace_back = traceback.extract_tb(ex_traceback)

    # Format stacktrace
    stack_trace = list()

    for trace in trace_back:
        stack_trace.append("File : %s , Line : %d, Func.Name : %s, Message : %s" % (trace[0], trace[1], trace[2], trace[3]))

    print("Exception type : %s " % ex_type.__name__)
    print("Exception message : %s" %ex_value)
    print("Stack trace : %s" %stack_trace)

जो निम्न आउटपुट देता है:

Exception type : ZeroDivisionError
Exception message : division by zero
Stack trace : ['File : .\\test.py , Line : 5, Func.Name : <module>, Message : ans = 1/0']

फ़ंक्शन sys.exc_info () आपको सबसे हाल के अपवाद के बारे में विवरण देता है। यह एक टपल देता है (type, value, traceback)

tracebackट्रेसबैक ऑब्जेक्ट का एक उदाहरण है। आप प्रदान किए गए तरीकों से ट्रेस को प्रारूपित कर सकते हैं। ट्रेसबैक प्रलेखन में अधिक पाया जा सकता है ।


3
का उपयोग करके e.__class__.__name__ अपवाद वर्ग को भी वापस कर सकते हैं।
kenorb

19

आप logger.exception("msg")ट्रेसबैक के साथ लॉगिंग अपवाद के लिए उपयोग कर सकते हैं :

try:
    #your code
except Exception as e:
    logger.exception('Failed: ' + str(e))

संयोग से, कक्षा e.msgका स्ट्रिंग प्रतिनिधित्व है Exception
MarkHu

5
या बस logger.exception(e)
mbdevpl


5

आप स्पष्ट रूप से BaseException प्रकार को निर्दिष्ट करने का प्रयास कर सकते हैं। हालांकि, यह केवल बेसएक्स अपवाद के डेरिवेटिव को पकड़ लेगा। हालांकि इसमें सभी कार्यान्वयन-प्रदान किए गए अपवाद शामिल हैं, यह संभवतः मनमाने ढंग से पुरानी शैली की कक्षाएं बढ़ाने के लिए भी है।

try:
  do_something()
except BaseException, e:
  logger.error('Failed to do something: ' + str(e))


2

भविष्य के संघर्षकर्ताओं के लिए, अजगर 3.8.2 में (और शायद उससे पहले कुछ संस्करण), वाक्यविन्यास है

except Attribute as e:
    print(e)

1

अपवाद का उपयोग करना str(e)या repr(e)उसका प्रतिनिधित्व करना, आपको वास्तविक स्टैक ट्रेस नहीं मिलेगा, इसलिए यह पता लगाना उपयोगी नहीं है कि अपवाद कहाँ है।

अन्य उत्तरों और लॉगिंग पैकेज डॉक्टर को पढ़ने के बाद, आसान डिबगिंग के लिए वास्तविक स्टैक ट्रेस को प्रिंट करने के लिए निम्नलिखित दो तरीके बहुत काम आते हैं:

logger.debug()पैरामीटर के साथ उपयोग करेंexc_info

try:
    # my code
exception SomeError as e:
    logger.debug(e, exc_info=True)

उपयोग logger.exception()

या हम logger.exception()अपवाद को मुद्रित करने के लिए सीधे उपयोग कर सकते हैं ।

try:
    # my code
exception SomeError as e:
    logger.exception(e)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.