Can we get stack trace from an exception? - python

To get stacktrace, I use:
except:
import traceback
print(traceback.format_exec())
Can I get stacktrace from an exception without using traceback? Example:
except Exception as e:
print(e)
print(e.traceback) #is there command like this?

Without using the traceback module, we should be able to get some further detail using sys.exc_info. This returns a tuple including traceback info:
try:
...
except Exception as e:
tb = sys.exec_info()[2]
...
The traceback object has info about the stack frame and line number the error occurred on.
This is what traceback uses under the hood.

You need traceback. You can use it together with e. You should import it at the beginning of your code, you don't need to import it every time an exception occurs.
import traceback
try:
...
except Exception as e:
tb = traceback.format_exc()
print(e)
print(tb)

Use the Traceback Module - More info can be found here:
https://docs.python.org/3/library/traceback.html
except Exception as e:
print(e)
traceback.print_exc(file=sys.stdout)
or save it as a variable first like the following:
except Exception as e:
print(e)
st = traceback.format_stack()
print(st)

Related

How to get python exception traceback in function

I have a function which should handle all errors:
def err(e):
import traceback
message = traceback.print_exc()
print(message)
if __name__ == "__main__":
try:
1/0 # just sample
except Exception as e:
err(e)
But it returns a short error like so:
integer division or modulo by zero
But I need more details (traceback) to check errors.
You're passing the exception to your function so why use traceback, you've got e there; just grab e.__traceback__ if you need the traceback:
import traceback
def err(e):
tb = e.__traceback__
# print traceback
traceback.print_tb(tb)
For an option that doesn't depend on dunders, you could use sys.exc_info and keep the traceback:
import traceback, sys
def err(e):
*_, tb = sys.exc_info()
# print traceback
traceback.print_tb(tb)
According to the python documentation:
traceback.print_exc([limit[, file]])
This is a shorthand for print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file). (In fact, it uses
sys.exc_info() to retrieve the same information in a thread-safe way
instead of using the deprecated variables.)
What you're essentially doing is just printing out the error message that is being produced by 1/0
If you want to print out a personalized error message you could do the following:
if __name__ == "__main__":
try:
1/0 # just sample
except Exception as e:
print 'This is the error I am expecting'

How to handle the EXCEPT message?

I am working with Python.
In my program I am using "try:" and "except:". Inside the "except" I want to send an email telling that some error has occurred and the action could not be executed, but I also like to add which is exactly the error.
Is there any way I can print the error message or use it in a variable?
I hope I made myself clear
Thanks a lot
Python >= 2.6
try:
...
except Exception as e:
print(e)
Python < 2.6
try:
...
except Exception, e:
print(e)
it will print the actuall message.
In Python < 2.6
try:
...
except Exception, e:
print(e)
In Python >= 2.6
try:
...
except Exception as e:
print(e)
This will give you the Exception message.
If you want the full traceback you can use the following:
import traceback
try:
...
except Exception, e:
print traceback.format_exc()

How do I get the stack trace from an Exception Object in Python 2.7?

How can I get the full stack trace from the Exception object itself?
Consider the following code as reduced example of the problem:
last_exception = None
try:
raise Exception('foo failed')
except Exception as e:
print "Exception Stack Trace %s" % e
The stack trace itself is not stored in the exception object itself. However, you can print the stack trace of the last recent exception using sys.exc_info() and the traceback module. Example:
import sys
import traceback
try:
raise Exception('foo failed')
except Exception as e:
traceback.print_tb(*sys.exc_info())
If you do not want to display the stack trace immediately, it should be possible to store the return value of sys.exc_info() somewhere.

where's the rest of ironpython exception?

I could be wrong, but it seems I'm only getting incomplete stack traces and exception messages when a SystemError is raised in IronPython. I'm doing this:
try:
with SQLConnection(DATASOURCES[SCHEDULEDB]) as db:
db.execute_sql( command + ' ' + ','.join(block) + ';' )
except Exception, e:
print 'caught an exception'
print "Unexpected error:", sys.exc_info()[0]
print e
raise
finally:
db.close()
engine.close()
however, all i'm seeing is this:
Traceback (most recent call last):
SystemError: The connection has been disabled.
Try:
import traceback
traceback.print_exc()
Instead of printing the exception object directly. In Python exception objects don't hold onto the stack trace directly - instead they're part of the trio of items in sys.exc_info().
You could also do:
import System
...
except System.Exception, e:
and you'll get a normal .NET exception object instead of the Python exception object.
There are some flags on the IronPython process that will set .NET exceptions to dump their stack trace as well:
ipy -X:ShowClrExceptions -X:ExceptionDetail my_script.py args

python exception message capturing

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
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))
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))
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 .
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)
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.
You can use logger.exception("msg") for logging exception with traceback:
try:
#your code
except Exception as e:
logger.exception('Failed: ' + str(e))
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)
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}")
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))
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.
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)
Use str(ex) to print execption
try:
#your code
except ex:
print(str(ex))
In Python 3, str(ex) gives us the error message. You could use repr(ex) to get the full text, including the name of the exception raised.
arr = ["a", "b", "c"]
try:
print(arr[5])
except IndexError as ex:
print(repr(ex)) # IndexError: list index out of range
print(str(ex)) # list index out of range
There is also a way to get the raw values passed to the exception class without having to change the content type.
For e.g I raise type codes with error messages in one of my frameworks.
try:
# TODO: Your exceptional code here
raise Exception((1, "Your code wants the program to exit"))
except Exception as e:
print("Exception Type:", e.args[0][0], "Message:", e.args[0][1])
Output
Exception Type: 1 Message: 'Your code wants the program to exit'
The easiest way to do this is available through the Polog library. Import it:
$ pip install polog
And use:
from polog import log, config, file_writer
config.add_handlers(file_writer('file.log'))
with log('message').suppress():
do_something()
Note how much less space the code has taken up vertically: only 2 lines.

Categories

Resources