Python print error info

When I catch an exception, how do I get the type, file, and line number?

None of these solutions find the line of code where the exception happened, @Apogentus. Maybe it’s because it’s Python 2 code or something but these solutions find the line of code much nearer where the exception is caught than where it was raised.

7 Answers 7

import sys, os try: raise NotImplementedError("No error") except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) 

You should be careful about unpacking sys.exc_info() into local variables, since if you get an exception in the except handler, the local vars could get kept in a circular reference and not GC’d. Best practice is to always just use slices off of sys.exc_info() instead. Or use other modules like traceback, as other posters have suggested.

@DanielPryden Python docs are also using the same unpacking method docs.python.org/2/library/traceback.html#traceback-examples

@RobM: Yes, it’s thread-safe. sys.exc_info() was introduced to deal with thread-safety problems in the previous API. Its output is specific to both the current thread and the current stack frame.

Simplest form that worked for me.

import traceback try: print(4/0) except ZeroDivisionError: print(traceback.format_exc()) 
Traceback (most recent call last): File "/path/to/file.py", line 51, in print(4/0) ZeroDivisionError: division by zero Process finished with exit code 0 

Source (Py v2.7.3) for traceback.format_exception() and called/related functions helps greatly. Embarrassingly, I always forget to Read the Source. I only did so for this after searching for similar details in vain. A simple question, «How to recreate the same output as Python for an exception, with all the same details?» This would get anybody 90+% to whatever they’re looking for. Frustrated, I came up with this example. I hope it helps others. (It sure helped me! 😉

import sys, traceback traceback_template = '''Traceback (most recent call last): File "%(filename)s", line %(lineno)s, in %(name)s %(type)s: %(message)s\n''' # Skipping the "actual line" item # Also note: we don't walk all the way through the frame stack in this example # see hg.python.org/cpython/file/8dffb76faacc/Lib/traceback.py#l280 # (Imagine if the 1/0, below, were replaced by a call to test() which did 1/0.) try: 1/0 except: # http://docs.python.org/2/library/sys.html#sys.exc_info exc_type, exc_value, exc_traceback = sys.exc_info() # most recent (if any) by default ''' Reason this _can_ be bad: If an (unhandled) exception happens AFTER this, or if we do not delete the labels on (not much) older versions of Py, the reference we created can linger. traceback.format_exc/print_exc do this very thing, BUT note this creates a temp scope within the function. ''' traceback_details = < 'filename': exc_traceback.tb_frame.f_code.co_filename, 'lineno' : exc_traceback.tb_lineno, 'name' : exc_traceback.tb_frame.f_code.co_name, 'type' : exc_type.__name__, 'message' : exc_value.message, # or see traceback._some_str() >del(exc_type, exc_value, exc_traceback) # So we don't leave our local labels/objects dangling # This still isn't "completely safe", though! # "Best (recommended) practice: replace all exc_type, exc_value, exc_traceback # with sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] print print traceback.format_exc() print print traceback_template % traceback_details print 

In specific answer to this query:

sys.exc_info()[0].__name__, os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename), sys.exc_info()[2].tb_lineno 

Источник

Читайте также:  How to add dictionary to dictionary python

How to get exception message in Python properly

What is the best way to get exceptions’ messages from components of standard library in Python? I noticed that in some cases you can get it via message field like this:

try: pass except Exception as ex: print(ex.message) 
try: pass except socket.error as ex: print(ex) 

You’re conflating two different things — except Foo as bar: is the same as except Foo, bar: (except the former is newer, and will continue to work in 3.x), whether the error comes with a message attribute or not is separate.

5 Answers 5

If you look at the documentation for the built-in errors, you’ll see that most Exception classes assign their first argument as a message attribute. Not all of them do though.

Notably, EnvironmentError (with subclasses IOError and OSError ) has a first argument of errno , second of strerror . There is no message . strerror is roughly analogous to what would normally be a message .

More generally, subclasses of Exception can do whatever they want. They may or may not have a message attribute. Future built-in Exception s may not have a message attribute. Any Exception subclass imported from third-party libraries or user code may not have a message attribute.

I think the proper way of handling this is to identify the specific Exception subclasses you want to catch, and then catch only those instead of everything with an except Exception , then utilize whatever attributes that specific subclass defines however you want.

If you must print something, I think that printing the caught Exception itself is most likely to do what you want, whether it has a message attribute or not.

Читайте также:  Php curl curlopt postfields get

You could also check for the message attribute if you wanted, like this, but I wouldn’t really suggest it as it just seems messy:

try: pass except Exception as e: # Just print(e) is cleaner and more likely what you want, # but if you insist on printing message specifically whenever possible. if hasattr(e, 'message'): print(e.message) else: print(e) 

Источник

How to get the name of an exception that was caught in Python?

For example, I am catching multiple (or all) exceptions, and want to print the name of the exception in an error message.

Why do you think you need this? Why not catch a more concrete exception (e.g. except NameError: ) to begin with?

I have a couple scenarios where I want to catch all exceptions (or a list of them), and want to print out the name of the exception in an error message.

You might want to check out the standard library’s traceback module, which has functions that do some nice formatting of exceptions and tracebacks.

@delnan this situation arises when you are testing if a function is raising an exception as programmed

I needed something like this to DRY up some code: several exceptions can be raised by the method I’m calling, each are handled with their own except statement, but the log entry is very similar in each case.

7 Answers 7

Here are a few different ways to get the name of the class of the exception:

  1. type(exception).__name__
  2. exception.__class__.__name__
  3. exception.__class__.__qualname__
try: foo = bar except Exception as exception: assert type(exception).__name__ == 'NameError' assert exception.__class__.__name__ == 'NameError' assert exception.__class__.__qualname__ == 'NameError' 

If you want the fully qualified class name (e.g. sqlalchemy.exc.IntegrityError instead of just IntegrityError ), you can use the function below, which I took from MB’s awesome answer to another question (I just renamed some variables to suit my tastes):

def get_full_class_name(obj): module = obj.__class__.__module__ if module is None or module == str.__class__.__module__: return obj.__class__.__name__ return module + '.' + obj.__class__.__name__ 
try: # except sqlalchemy.exc.SQLAlchemyError as e: print(get_full_class_name(e)) # sqlalchemy.exc.IntegrityError 

You can print the exception using some formated strings:

try: #Code to execute except Exception as err: print(f" was raised: ") 

You can also use sys.exc_info() . exc_info() returns 3 values: type, value, traceback. On documentation: https://docs.python.org/3/library/sys.html#sys.exc_info

import sys try: foo = bar except Exception: exc_type, value, traceback = sys.exc_info() assert exc_type.__name__ == 'NameError' print "Failed with exception [%s]" % exc_type.__name__ 

This works, but it seems like there must be an easier, more direct way?

try: foo = bar except Exception as exception: assert repr(exception) == '''NameError("name 'bar' is not defined",)''' name = repr(exception).split('(')[0] assert name == 'NameError' 

Replace except Exception as exception with the type of exception you’d like to catch, i.e. except NameError as exception .

Читайте также:  Профессия разработчик python с нуля до профи skills factory

The other answers here are great for exploration purposes, but if the primary goal is to log the exception (including the name of the exception), perhaps consider using logging.exception instead of print?

When you say «name» this could mean a couple of things: it could mean only the «immediate» classname, or it could mean the fully qualified name. Usually the latter will be much more useful and less error-prone: I’ve come across more than one case of 2 or more types with same «immediate» classname but from different packages.

If you want to print or log the fully qualified name this is one of the simplest things to do:

try: do_something() except BaseException as e: logger.error(f'whoops! : ') # or maybe print(f'whoops! : ', file=sys.stderr) 

The fully qualified classname will then be printed out like this: «», and then be followed by the exception message. The OP says he wants «for example», to print a message, so assert statements as in the chosen answer don’t seem to be called for.

The answer by MrName is also not irrelevant, and does make a sensible suggestion! if in the above you replaced logger.error(. ) with logger.exception(‘whoops!’) (NB a user message is a required param) you’d get your exception’s fully qualified name logged, not to mention its message, and a stack trace for free.

PS as suggested by the name, JSONDecodeError in my example is an Error , not an Exception (it is a subclass of ValueError ). Catching BaseException (the superclass of both Error and Exception ) usually makes life easier when you’re not fishing for a specific exception. The OP says he wants to catch «all» exceptions.

Источник

Оцените статью