python exception message capturing

PythonExceptionLoggingExcept

Python Problem Overview


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))

This doesn't seem to work, I get syntax error, what is the proper way of doing this for logging all kind of exceptions to a file

Python Solutions


Solution 1 - Python

You have to define which type of exception you want to catch. So write except Exception, e: instead of except, e: for a general exception (that will be logged anyway).

Other possibility is to write your whole try/except code this way:

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))

in Python 3.x and modern versions of Python 2.x use except Exception as e instead of 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))

Solution 2 - Python

The syntax is no longer supported in python 3. Use the following instead.

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

Solution 3 - Python

If you want the error class, error message, and stack trace, use sys.exc_info().

Minimal working code with some formatting:

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)

Which gives the following output:

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

The function sys.exc_info() gives you details about the most recent exception. It returns a tuple of (type, value, traceback).

traceback is an instance of traceback object. You can format the trace with the methods provided. More can be found in the traceback documentation .

Solution 4 - Python

There are some cases where you can use the e.message or e.messages.. But it does not work in all cases. Anyway the more safe is to use the str(e)

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

Solution 5 - Python

Updating this to something simpler for logger (works for both python 2 and 3). You do not need traceback module.

import logging

logger = logging.Logger('catch_all')

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

This is now the old way (though still works):

import sys, traceback

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

exc_value is the error message.

Solution 6 - Python

You can use logger.exception("msg") for logging exception with traceback:

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

Solution 7 - Python

After python 3.6, you can use formatted string literal. It's neat! (https://docs.python.org/3/whatsnew/3.6.html#whatsnew36-pep498)

try
 ...
except Exception as e:
    logger.error(f"Failed to upload to ftp: {e}")

Solution 8 - Python

Using str(e) or repr(e) to represent the exception, you won't get the actual stack trace, so it is not helpful to find where the exception is.

After reading other answers and the logging package doc, the following two ways works great to print the actual stack trace for easier debugging:

use logger.debug() with parameter exc_info

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

use logger.exception()

or we can directly use logger.exception() to print the exception.

try:
    # my code
except SomeError as e:
    logger.exception(e)

Solution 9 - Python

You can try specifying the BaseException type explicitly. However, this will only catch derivatives of BaseException. While this includes all implementation-provided exceptions, it is also possibly to raise arbitrary old-style classes.

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

Solution 10 - Python

Use str(ex) to print execption

try:
   #your code
except ex:
   print(str(ex))

Solution 11 - Python

for the future strugglers, in python 3.8.2(and maybe a few versions before that), the syntax is

except Attribute as e:
    print(e)

Solution 12 - Python

If you want to see the original error message, (file & line number)

import traceback
try:
    print(3/0)
except Exception as e:    
    traceback.print_exc() 

This will show you the same error message as if you didn't use try-except.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHellnarView Question on Stackoverflow
Solution 1 - PythoneumiroView Answer on Stackoverflow
Solution 2 - PythonsjtaheriView Answer on Stackoverflow
Solution 3 - PythonKavindu DodanduwaView Answer on Stackoverflow
Solution 4 - PythonSlipstreamView Answer on Stackoverflow
Solution 5 - PythonbernieyView Answer on Stackoverflow
Solution 6 - PythonPeterView Answer on Stackoverflow
Solution 7 - PythonChuan MaView Answer on Stackoverflow
Solution 8 - PythonjdhaoView Answer on Stackoverflow
Solution 9 - PythonHeini HøgnasonView Answer on Stackoverflow
Solution 10 - PythonNiraj TrivediView Answer on Stackoverflow
Solution 11 - PythonsyterView Answer on Stackoverflow
Solution 12 - PythonstarrietView Answer on Stackoverflow