Get error text python

In this Python Tutorial let us learn about the 3 different pieces of information that you can extract and use from the Exceptions caught on your except clauses, and see the best ways to use each of these pieces in our Python programs.

In this Python Tutorial let us learn about the 3 different pieces of information that you can extract and use from the Exceptions caught on your except clauses, and see the best ways to use each of these pieces in our Python programs.

Let us start by learning what the 3 pieces of information are.

What kind of information can you get from Exceptions?

You can get the following 3 pieces of data from exceptions

  • Exception Type,
  • Exception Value a.k.a Error Message, and
  • Stack-trace or Traceback Object.

All three of the above information is printed out by the Python Interpreter when our program crashes due to an exception as shown in the following example

>> my_list = [1,2]
>> print (my_list[3])
Traceback (most recent call last):

  File "<ipython-input-35-63c7f9106be5>", line 1, in <module>
    print (my_list[3])

IndexError: list index out of range

Lines 3,4,5,6 shows the Stack-trace
Line 7 shows the Exception type and Error Message.

Our focus in this article is to learn how to extract the above 3 pieces individually in our except clauses and print them out as needed.

Hence, the rest of the article is all about answering the following questions

  • what does each of the information in the above list mean,
  • how to extract each of these 3 pieces individually and
  • how to use these pieces in our programs.

Piece#1: Printing Exception Type

The Exception Type refers to the class to which the Exception that you have just caught belongs to.

Extracting Piece#1 (Exception Type)

Let us improve our Example 1 above by putting the problematic code into try and except clauses.

try:
  my_list = [1,2]
  print (my_list[3])
except Exception as e:
  print(type(e))

Here, in the try clause, we have declared a List named my_list and initialized the list with 2 items. Then we have tried to print the 3rd/non-existent item in the list.

The except clause catches the IndexError exception and prints out Exception type.

On running the code, we will get the following output

<class 'IndexError'>

As you can see we just extracted and printed out the information about the class to which the exception that we have just caught belongs to!

But how exactly did we do that?
If you have a look at the except clause. In the line

except Exception as e:

what we have done is, we have assigned the caught exception to an object named “e”. Then by using the built-in python function type(), we have printed out the class name that the object e belongs to.

print(type(e))

Where to get more details about Exception Types

Now that we have the “Exception Type”, next we will probably need to get some information about that particular type so that we can get a better understanding of why our code has failed. In order to do that, the best place to start is the official documentation.

For built in exceptions you can have a look at the Python Documentation

For Exception types that come with the libraries that you use with your code, refer to the documentation of your library.

Piece#2: Printing Exception Value a.k.a Error message

The Exception type is definitely useful for debugging, but, a message like IndexError might sound cryptic and a good understandable error-message will make our job of debugging easier without having to look at the documentation.

In other words, if your program is to be run on the command line and you wish to log why the program just crashed then it is better to use an “Error message” rather than an “Exception Type”.

The example below shows how to print such an Error message.

try:
  my_list = [1,2]
  print (my_list[3])
except Exception as e:
  print(e)

This will print the default error message as follows

list index out of range

Each Exception type comes with its own error message. This can be retrieved using the built-in function print().

Say your program is going to be run by a not-so-tech-savvy user, in that case, you might want to print something friendlier. You can do so by passing in the string to be printed along with the constructor as follows.

try:
  raise IndexError('Custom message about IndexError')
except Exception as e:
  print(e)

This will print

Custom message about IndexError

To understand how the built-in function print() does this magic, and see some more examples of manipulating these error messages, I recommend reading my other article in the link below.

Python Exception Tutorial: Printing Error Messages (5 Examples!)

If you wish to print both the Error message and the Exception type, which I recommend, you can do so like below.

try:
  my_list = [1,2]
  print (my_list[3])
except Exception as e:
  print(repr(e))

This will print something like

IndexError('list index out of range')

Now that we have understood how to get control over the usage of Pieces 1 and 2, let us go ahead and look at the last and most important piece for debugging, the stack-trace which tells us where exactly in our program have the Exception occurred.

Piece#3: Printing/Logging the stack-trace using the traceback object

Stack-trace in Python is packed into an object named traceback object.

This is an interesting one as the traceback class in Python comes with several useful methods to exercise complete control over what is printed.

Let us see how to use these options using some examples!

import traceback

try:
  my_list = [1,2]
  print (my_list[3])
except Exception:
  traceback.print_exc()

This will print something like

Traceback (most recent call last):
  File "<ipython-input-38-f9a1ee2cf77a>", line 5, in <module>
    print (my_list[3])
IndexError: list index out of range

which contains the entire error messages printed by the Python interpreter if we fail to handle the exception.

Here, instead of crashing the program, we have printed this entire message using our exception handler with the help of the print_exc() method of the traceback class.

The above Example-6 is too simple, as, in the real-world, we will normally have several nested function calls which will result in a deeper stack. Let us see an example of how to control the output in such situations.

def func3():
  my_list = [1,2]
  print (my_list[3])

def func2():
  print('calling func3')
  func3()

def func1():
  print('calling func2')
  func2()

try:
  print('calling func1')
  func1()
except Exception as e:
    traceback.print_exc()

Here in the try clause we call func1(), which in-turn calls func2(), which in-turn calls func3(), which produces an IndexError. Running the code above we get the following output

calling func1
calling func2
calling func3
Traceback (most recent call last):
  File "<ipython-input-42-2267707e164f>", line 15, in <module>
    func1()
  File "<ipython-input-42-2267707e164f>", line 11, in func1
    func2()
  File "<ipython-input-42-2267707e164f>", line 7, in func2
    func3()
  File "<ipython-input-42-2267707e164f>", line 3, in func3
    print (my_list[3])
IndexError: list index out of range

Say we are not interested in some of the above information. Say we just want to print out the Traceback and skip the error message and Exception type (the last line above), then we can modify the code like shown below.

def func3():
  my_list = [1,2]
  print (my_list[3])

def func2():
  func3()

def func1():
  func2()

try:
  func1()
except Exception as e:
    traceback_lines = traceback.format_exc().splitlines()
    for line in traceback_lines:
      if line != traceback_lines[-1]:
        print(line)

Here we have used the format_exc() method available in the traceback class to get the traceback information as a string and used splitlines() method to transform the string into a list of lines and stored that in a list object named traceback_lines

Then with the help of a simple for loop we have skipped printing the last line with index of -1 to get an output like below

Traceback (most recent call last):
  File "<ipython-input-43-aff649563444>", line 3, in <module>
    func1()
  File "<ipython-input-42-2267707e164f>", line 11, in func1
    func2()
  File "<ipython-input-42-2267707e164f>", line 7, in func2
    func3()
  File "<ipython-input-42-2267707e164f>", line 3, in func3
    print (my_list[3])

Another interesting variant of formatting the information in the traceback object is to control the depth of stack that is actually printed out.

If your program uses lots of external library code, odds are the stack will get very deep, and printing out each and every level of function call might not be very useful. If you ever find yourself in such a situation you can set the limit argument in the print_exc() method like shown below.

traceback.print_exc(limit=2, file=sys.stdout)

This will limit the number of levels to 2. Let us use this line of code in our Example and see how that behaves

def func3():
  my_list = [1,2]
  print (my_list[3])

def func2():
  func3()

def func1():
  func2()

try:
  func1()
except Exception as e:
  traceback.print_exc(limit=2)

This will print

Traceback (most recent call last):
  File "<ipython-input-44-496132ff4faa>", line 12, in <module>
    func1()
  File "<ipython-input-44-496132ff4faa>", line 9, in func1
    func2()
IndexError: list index out of range

As you can see, we have printed only 2 levels of the stack and skipped the 3rd one, just as we wanted!

You can do more things with traceback like formatting the output to suit your needs. If you are interested to learn even more things to do, refer to the official documentation on traceback here

Now that we have seen how to exercise control over what gets printed and how to format them, next let us have a look at some best practices on when to use which piece of information

Best Practices while Printing Exception messages

When to Use Which Piece

  • Use Piece#1 only on very short programs and only during the development/testing phase to get some clues on the Exceptions without letting the interpreter crash your program. Once finding out, implement specific handlers to do something about these exceptions. If you are not sure how to handle the exceptions have a look at my other article below where I have explained 3 ways to handle Exceptions
    Exceptions in Python: Everything You Need To Know!
  • Use Piece#2 to print out some friendly information either for yourself or for your user to inform them what exactly is happening.
  • Use all 3 pieces on your finished product, so that if an exception ever occurs while your program is running on your client’s computer, you can log the errors and have use that information to fix your bugs.

Where to print

One point worth noting here is that the default file that print() uses is the stdout file stream and not the stderr stream. To use stderr instead, you can modify the code like this

import sys
try:
  #some naughty statements that irritate us with exceptions
except Exception as e:
  print(e, file=sys.stderr)

The above code is considered better practice, as errors are meant to go to stderr and not stdout.

You can always print these into a separate log file too if that is what you need. This way, you can organize the logs collected in a better manner by separating the informational printouts from the error printouts.

How to print into log files

If you are going to use a log file I suggest using python’s logging module instead of print() statements, as described here

If you are interested in learning how to manually raise exceptions, and what situations you might need to do that you can read this article below

Python: Manually throw/raise an Exception using the “raise” statement

If you are interested in catching and handling multiple exception in a single except clause, you can this article below

Python: 3 Ways to Catch Multiple Exceptions in a single “except” clause

And with that, I will conclude this article!
I hope you enjoyed reading this article and got some value out of it!
Feel free to share it with your friends and colleagues!

Содержание

  1. 8. Errors and Exceptions¶
  2. 8.1. Syntax Errors¶
  3. 8.2. Exceptions¶
  4. 8.3. Handling Exceptions¶
  5. 8.4. Raising Exceptions¶
  6. 8.5. Exception Chaining¶
  7. 8.6. User-defined Exceptions¶
  8. 8.7. Defining Clean-up Actions¶
  9. 8.8. Predefined Clean-up Actions¶
  10. 8.9. Raising and Handling Multiple Unrelated Exceptions¶
  11. 8.10. Enriching Exceptions with Notes¶
  12. Python Exception to string
  13. What kind of information can you get from Exceptions?
  14. Piece#1: Printing Exception Type
  15. Extracting Piece#1 (Exception Type)
  16. Where to get more details about Exception Types
  17. Piece#2: Printing Exception Value a.k.a Error message
  18. Piece#3: Printing/Logging the stack-trace using the traceback object
  19. Best Practices while Printing Exception messages
  20. When to Use Which Piece
  21. Where to print
  22. How to print into log files

8. Errors and Exceptions¶

Until now error messages haven’t been more than mentioned, but if you have tried out the examples you have probably seen some. There are (at least) two distinguishable kinds of errors: syntax errors and exceptions.

8.1. Syntax Errors¶

Syntax errors, also known as parsing errors, are perhaps the most common kind of complaint you get while you are still learning Python:

The parser repeats the offending line and displays a little ‘arrow’ pointing at the earliest point in the line where the error was detected. The error is caused by (or at least detected at) the token preceding the arrow: in the example, the error is detected at the function print() , since a colon ( ‘:’ ) is missing before it. File name and line number are printed so you know where to look in case the input came from a script.

8.2. Exceptions¶

Even if a statement or expression is syntactically correct, it may cause an error when an attempt is made to execute it. Errors detected during execution are called exceptions and are not unconditionally fatal: you will soon learn how to handle them in Python programs. Most exceptions are not handled by programs, however, and result in error messages as shown here:

The last line of the error message indicates what happened. Exceptions come in different types, and the type is printed as part of the message: the types in the example are ZeroDivisionError , NameError and TypeError . The string printed as the exception type is the name of the built-in exception that occurred. This is true for all built-in exceptions, but need not be true for user-defined exceptions (although it is a useful convention). Standard exception names are built-in identifiers (not reserved keywords).

The rest of the line provides detail based on the type of exception and what caused it.

The preceding part of the error message shows the context where the exception occurred, in the form of a stack traceback. In general it contains a stack traceback listing source lines; however, it will not display lines read from standard input.

Built-in Exceptions lists the built-in exceptions and their meanings.

8.3. Handling Exceptions¶

It is possible to write programs that handle selected exceptions. Look at the following example, which asks the user for input until a valid integer has been entered, but allows the user to interrupt the program (using Control — C or whatever the operating system supports); note that a user-generated interruption is signalled by raising the KeyboardInterrupt exception.

The try statement works as follows.

First, the try clause (the statement(s) between the try and except keywords) is executed.

If no exception occurs, the except clause is skipped and execution of the try statement is finished.

If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then, if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try/except block.

If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above.

A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement. An except clause may name multiple exceptions as a parenthesized tuple, for example:

A class in an except clause is compatible with an exception if it is the same class or a base class thereof (but not the other way around — an except clause listing a derived class is not compatible with a base class). For example, the following code will print B, C, D in that order:

Note that if the except clauses were reversed (with except B first), it would have printed B, B, B — the first matching except clause is triggered.

When an exception occurs, it may have associated values, also known as the exception’s arguments. The presence and types of the arguments depend on the exception type.

The except clause may specify a variable after the exception name. The variable is bound to the exception instance which typically has an args attribute that stores the arguments. For convenience, builtin exception types define __str__() to print all the arguments without explicitly accessing .args .

The exception’s __str__() output is printed as the last part (‘detail’) of the message for unhandled exceptions.

BaseException is the common base class of all exceptions. One of its subclasses, Exception , is the base class of all the non-fatal exceptions. Exceptions which are not subclasses of Exception are not typically handled, because they are used to indicate that the program should terminate. They include SystemExit which is raised by sys.exit() and KeyboardInterrupt which is raised when a user wishes to interrupt the program.

Exception can be used as a wildcard that catches (almost) everything. However, it is good practice to be as specific as possible with the types of exceptions that we intend to handle, and to allow any unexpected exceptions to propagate on.

The most common pattern for handling Exception is to print or log the exception and then re-raise it (allowing a caller to handle the exception as well):

The try … except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:

The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try … except statement.

Exception handlers do not handle only exceptions that occur immediately in the try clause, but also those that occur inside functions that are called (even indirectly) in the try clause. For example:

8.4. Raising Exceptions¶

The raise statement allows the programmer to force a specified exception to occur. For example:

The sole argument to raise indicates the exception to be raised. This must be either an exception instance or an exception class (a class that derives from BaseException , such as Exception or one of its subclasses). If an exception class is passed, it will be implicitly instantiated by calling its constructor with no arguments:

If you need to determine whether an exception was raised but don’t intend to handle it, a simpler form of the raise statement allows you to re-raise the exception:

8.5. Exception Chaining¶

If an unhandled exception occurs inside an except section, it will have the exception being handled attached to it and included in the error message:

To indicate that an exception is a direct consequence of another, the raise statement allows an optional from clause:

This can be useful when you are transforming exceptions. For example:

It also allows disabling automatic exception chaining using the from None idiom:

For more information about chaining mechanics, see Built-in Exceptions .

8.6. User-defined Exceptions¶

Programs may name their own exceptions by creating a new exception class (see Classes for more about Python classes). Exceptions should typically be derived from the Exception class, either directly or indirectly.

Exception classes can be defined which do anything any other class can do, but are usually kept simple, often only offering a number of attributes that allow information about the error to be extracted by handlers for the exception.

Most exceptions are defined with names that end in “Error”, similar to the naming of the standard exceptions.

Many standard modules define their own exceptions to report errors that may occur in functions they define.

8.7. Defining Clean-up Actions¶

The try statement has another optional clause which is intended to define clean-up actions that must be executed under all circumstances. For example:

If a finally clause is present, the finally clause will execute as the last task before the try statement completes. The finally clause runs whether or not the try statement produces an exception. The following points discuss more complex cases when an exception occurs:

If an exception occurs during execution of the try clause, the exception may be handled by an except clause. If the exception is not handled by an except clause, the exception is re-raised after the finally clause has been executed.

An exception could occur during execution of an except or else clause. Again, the exception is re-raised after the finally clause has been executed.

If the finally clause executes a break , continue or return statement, exceptions are not re-raised.

If the try statement reaches a break , continue or return statement, the finally clause will execute just prior to the break , continue or return statement’s execution.

If a finally clause includes a return statement, the returned value will be the one from the finally clause’s return statement, not the value from the try clause’s return statement.

A more complicated example:

As you can see, the finally clause is executed in any event. The TypeError raised by dividing two strings is not handled by the except clause and therefore re-raised after the finally clause has been executed.

In real world applications, the finally clause is useful for releasing external resources (such as files or network connections), regardless of whether the use of the resource was successful.

8.8. Predefined Clean-up Actions¶

Some objects define standard clean-up actions to be undertaken when the object is no longer needed, regardless of whether or not the operation using the object succeeded or failed. Look at the following example, which tries to open a file and print its contents to the screen.

The problem with this code is that it leaves the file open for an indeterminate amount of time after this part of the code has finished executing. This is not an issue in simple scripts, but can be a problem for larger applications. The with statement allows objects like files to be used in a way that ensures they are always cleaned up promptly and correctly.

After the statement is executed, the file f is always closed, even if a problem was encountered while processing the lines. Objects which, like files, provide predefined clean-up actions will indicate this in their documentation.

There are situations where it is necessary to report several exceptions that have occurred. This is often the case in concurrency frameworks, when several tasks may have failed in parallel, but there are also other use cases where it is desirable to continue execution and collect multiple errors rather than raise the first exception.

The builtin ExceptionGroup wraps a list of exception instances so that they can be raised together. It is an exception itself, so it can be caught like any other exception.

By using except* instead of except , we can selectively handle only the exceptions in the group that match a certain type. In the following example, which shows a nested exception group, each except* clause extracts from the group exceptions of a certain type while letting all other exceptions propagate to other clauses and eventually to be reraised.

Note that the exceptions nested in an exception group must be instances, not types. This is because in practice the exceptions would typically be ones that have already been raised and caught by the program, along the following pattern:

8.10. Enriching Exceptions with Notes¶

When an exception is created in order to be raised, it is usually initialized with information that describes the error that has occurred. There are cases where it is useful to add information after the exception was caught. For this purpose, exceptions have a method add_note(note) that accepts a string and adds it to the exception’s notes list. The standard traceback rendering includes all notes, in the order they were added, after the exception.

For example, when collecting exceptions into an exception group, we may want to add context information for the individual errors. In the following each exception in the group has a note indicating when this error has occurred.

Источник

Python Exception to string

In this Python Tutorial let us learn about the 3 different pieces of information that you can extract and use from the Exceptions caught on your except clauses, and see the best ways to use each of these pieces in our Python programs.

Let us start by learning what the 3 pieces of information are.

What kind of information can you get from Exceptions?

You can get the following 3 pieces of data from exceptions

  • Exception Type,
  • Exception Value a.k.a Error Message, and
  • Stack-trace or Traceback Object.

All three of the above information is printed out by the Python Interpreter when our program crashes due to an exception as shown in the following example

Lines 3,4,5,6 shows the Stack-trace
Line 7 shows the Exception type and Error Message.

Our focus in this article is to learn how to extract the above 3 pieces individually in our except clauses and print them out as needed.

Hence, the rest of the article is all about answering the following questions

  • what does each of the information in the above list mean,
  • how to extract each of these 3 pieces individually and
  • how to use these pieces in our programs.

Piece#1: Printing Exception Type

The Exception Type refers to the class to which the Exception that you have just caught belongs to.

Let us improve our Example 1 above by putting the problematic code into try and except clauses.

Here, in the try clause, we have declared a List named my_list and initialized the list with 2 items. Then we have tried to print the 3rd/non-existent item in the list.

The except clause catches the IndexError exception and prints out Exception type.

On running the code, we will get the following output

As you can see we just extracted and printed out the information about the class to which the exception that we have just caught belongs to!

But how exactly did we do that?
If you have a look at the except clause. In the line

what we have done is, we have assigned the caught exception to an object named “e”. Then by using the built-in python function type(), we have printed out the class name that the object e belongs to.

Where to get more details about Exception Types

Now that we have the “Exception Type”, next we will probably need to get some information about that particular type so that we can get a better understanding of why our code has failed. In order to do that, the best place to start is the official documentation.

For built in exceptions you can have a look at the Python Documentation

For Exception types that come with the libraries that you use with your code, refer to the documentation of your library.

Piece#2: Printing Exception Value a.k.a Error message

The Exception type is definitely useful for debugging, but, a message like IndexError might sound cryptic and a good understandable error-message will make our job of debugging easier without having to look at the documentation.

In other words, if your program is to be run on the command line and you wish to log why the program just crashed then it is better to use an “Error message” rather than an “Exception Type”.

The example below shows how to print such an Error message.

This will print the default error message as follows

Each Exception type comes with its own error message. This can be retrieved using the built-in function print().

Say your program is going to be run by a not-so-tech-savvy user, in that case, you might want to print something friendlier. You can do so by passing in the string to be printed along with the constructor as follows.

This will print

To understand how the built-in function print() does this magic, and see some more examples of manipulating these error messages, I recommend reading my other article in the link below.

If you wish to print both the Error message and the Exception type, which I recommend, you can do so like below.

This will print something like

Now that we have understood how to get control over the usage of Pieces 1 and 2, let us go ahead and look at the last and most important piece for debugging, the stack-trace which tells us where exactly in our program have the Exception occurred.

Piece#3: Printing/Logging the stack-trace using the traceback object

Stack-trace in Python is packed into an object named traceback object.

This is an interesting one as the traceback class in Python comes with several useful methods to exercise complete control over what is printed.

Let us see how to use these options using some examples!

This will print something like

which contains the entire error messages printed by the Python interpreter if we fail to handle the exception.

Here, instead of crashing the program, we have printed this entire message using our exception handler with the help of the print_exc() method of the traceback class.

The above Example-6 is too simple, as, in the real-world, we will normally have several nested function calls which will result in a deeper stack. Let us see an example of how to control the output in such situations.

Here in the try clause we call func1(), which in-turn calls func2(), which in-turn calls func3(), which produces an IndexError. Running the code above we get the following output

Say we are not interested in some of the above information. Say we just want to print out the Traceback and skip the error message and Exception type (the last line above), then we can modify the code like shown below.

Here we have used the format_exc() method available in the traceback class to get the traceback information as a string and used splitlines() method to transform the string into a list of lines and stored that in a list object named traceback_lines

Then with the help of a simple for loop we have skipped printing the last line with index of -1 to get an output like below

Another interesting variant of formatting the information in the traceback object is to control the depth of stack that is actually printed out.

If your program uses lots of external library code, odds are the stack will get very deep, and printing out each and every level of function call might not be very useful. If you ever find yourself in such a situation you can set the limit argument in the print_exc() method like shown below.

This will limit the number of levels to 2. Let us use this line of code in our Example and see how that behaves

This will print

As you can see, we have printed only 2 levels of the stack and skipped the 3rd one, just as we wanted!

You can do more things with traceback like formatting the output to suit your needs. If you are interested to learn even more things to do, refer to the official documentation on traceback here

Now that we have seen how to exercise control over what gets printed and how to format them, next let us have a look at some best practices on when to use which piece of information

Best Practices while Printing Exception messages

When to Use Which Piece

  • Use Piece#1 only on very short programs and only during the development/testing phase to get some clues on the Exceptions without letting the interpreter crash your program. Once finding out, implement specific handlers to do something about these exceptions. If you are not sure how to handle the exceptions have a look at my other article below where I have explained 3 ways to handle Exceptions
    Exceptions in Python: Everything You Need To Know!
  • Use Piece#2 to print out some friendly information either for yourself or for your user to inform them what exactly is happening.
  • Use all 3 pieces on your finished product, so that if an exception ever occurs while your program is running on your client’s computer, you can log the errors and have use that information to fix your bugs.

Where to print

One point worth noting here is that the default file that print() uses is the stdout file stream and not the stderr stream. To use stderr instead, you can modify the code like this

The above code is considered better practice, as errors are meant to go to stderr and not stdout.

You can always print these into a separate log file too if that is what you need. This way, you can organize the logs collected in a better manner by separating the informational printouts from the error printouts.

How to print into log files

If you are going to use a log file I suggest using python’s logging module instead of print() statements, as described here

If you are interested in learning how to manually raise exceptions, and what situations you might need to do that you can read this article below

If you are interested in catching and handling multiple exception in a single except clause, you can this article below

And with that, I will conclude this article!
I hope you enjoyed reading this article and got some value out of it!
Feel free to share it with your friends and colleagues!

Источник

Prerequisite: Python Traceback

To print stack trace for an exception the suspicious code will be kept in the try block and except block will be employed to handle the exception generated. Here we will be printing the stack trace to handle the exception generated. The printing stack trace for an exception helps in understanding the error and what went wrong with the code. Not just this, the stack trace also shows where the error occurred.

The general structure of a stack trace for an exception: 

  • Traceback for the most recent call.
  • Location of the program.
  • Line in the program where the error was encountered.
  • Name of the error: relevant information about the exception
     

Example: 

Traceback (most recent call last):
  File "C:/Python27/hdg.py", line 5, in 
    value=A[5]
IndexError: list index out of range

Method 1: By using print_exc() method.

This method prints exception information and stack trace entries from traceback object tb to file.

Syntax: traceback.print_exc(limit=Nonefile=Nonechain=True)

Parameters: This method accepts the following parameters:

  • if a limit argument is positive, Print up to limit stack trace entries from traceback object tb (starting from the caller’s frame). Otherwise, print the last abs(limit) entries. If the limit argument is None, all entries are printed.
  • If the file argument is None, the output goes to sys.stderr; otherwise, it should be an open file or file-like object to receive the output.
  • If chain argument is true (the default), then chained exceptions will be printed as well, like the interpreter itself does when printing an unhandled exception.

Return: None.

Code:

Python3

import traceback

A = [1, 2, 3, 4]

try:

    value = A[5]

except:

    traceback.print_exc()

print("end of program")

Output: 

Traceback (most recent call last):
  File "C:/Python27/hdg.py", line 8, in 
    value=A[5]
IndexError: list index out of range
end of program

Method 2: By using print_exception() method.

This method prints exception information and stack trace entries from traceback object tb to file.

Syntax : traceback.print_exception(etypevaluetblimit=Nonefile=Nonechain=True)

Parameters: This method accepts the following parameters:

  • if tb argument is not None, it prints a header Traceback (most recent call last):
  • it prints the exception etype and value after the stack trace
  • if type(value) argument is SyntaxError and value has the appropriate format, it prints the line where the syntax error occurred with a caret indicating the approximate position of the error.
  • if a limit argument is positive, Print up to limit stack trace entries from traceback object tb (starting from the caller’s frame). Otherwise, print the last abs(limit) entries. If the limit argument is None, all entries are printed.
  • If the file argument is None, the output goes to sys.stderr; otherwise, it should be an open file or file-like object to receive the output.
  • If chain argument is true (the default), then chained exceptions will be printed as well, like the interpreter itself does when printing an unhandled exception.

Return: None.

Code:

Python3

import traceback

import sys

a = 4

b = 0

try:

    value = a / b

except:

    traceback.print_exception(*sys.exc_info())

print("end of program")

Output: 

Traceback (most recent call last):
  File "C:/Python27/hdg.py", line 10, in 
    value=a/b
ZeroDivisionError: integer division or modulo by zero
end of program

  1. Capture Exception Message in Python Using logger.exception() Method
  2. Capture Exception Message in Python Using logger.error() Method
  3. Capture Exception Message in Python Using the print() Method

Exception Message in Python

This tutorial will explain different ways to capture exception messages in Python. The exception handling is used to respond to the exceptions that occur during the execution of the program. It is important to handle exceptions; otherwise, a program will crash whenever some exception occurs.

The try ... except statement handles exceptions in Python. But we also need to capture the details of exception that occurs during the code execution, so that it can be solved. The various methods that can be used to capture the exception messages in Python are explained below.

Capture Exception Message in Python Using logger.exception() Method

The logger.exception() method returns an error message and the log trace, which includes the details like the code line number at which the exception has occurred. The logger.exception() method must be placed within except statement; otherwise, it will not work correctly in any other place.

The below code example demonstrates the proper use of the logger.exception() method with try ... except statement to capture the exception message in Python.

import logging

logger = logging.getLogger()

try:
    x = 1/0
except Exception as e:
    logger.exception('Exception occurred while code execution: ' + str(e))

Output:

Exception occurred while code execution: division by zero
Traceback (most recent call last):
  File "<ipython-input-27-912703271615>", line 5, in <module>
    x = 1/0
ZeroDivisionError: division by zero

Capture Exception Message in Python Using logger.error() Method

The logger.error() method returns the error message only whenever exceptions occur within the try block. The code example of how the logger.error() method can capture exception messages in Python is given below.

import logging

logger = logging.getLogger()

try:
    x = 1/0
except Exception as e:
    logger.error('Exception occurred while code execution: ' + str(e))

Output:

Exception occurred while code execution: division by zero

As we can notice in the above example, the str(e) method only gets the exception message from the exception e object and not the exception type.

The repr(e) method can be used to get the exception type along the exception message. The below code example demonstrate the use and output of the repr(e) method:

import logging
logger = logging.getLogger()
try:
    x = 1/0
except Exception as e:
    logger.error('Exception occurred while code execution: ' + repr(e))

Output:

Exception occurred while code execution: ZeroDivisionError('division by zero',)

Capture Exception Message in Python Using the print() Method

We can also use the print() method to print the exception message. The example code below demonstrates how to capture and print an exception message in Python using the print() method.

Example code:

try:
    x = 1/0
except Exception as e:
    print('Exception occurred while code execution: ' + repr(e))

Output:

Exception occurred while code execution: ZeroDivisionError('division by zero',)

This post shows how to print the message and details of an Exception in Python. Sometimes, when we encounter errors, the messages aren’t clear or misleading. Also, the details may be lacking. We used Python 3.7.0 for this post.

Catch Specific Exception And Show The Message Or Details

Python has a
trycatch feature to enable programmers’ code to handle errors elegantly. It has a different name for it, though. We can call it
tryexcept in Python. All the codes that may cause errors we place in the
try block. Meanwhile, we handle the errors in the
except block. Finally, we have the
else block that always runs.

import sys

def main():

    try:

        x = int(‘Not a number’)

    except ValueError as error:

        print(f‘Exception Message -> {sys.exc_info()[1]}’)

        print(f‘Details -> {sys.exc_info()}’)

    else:

        print(‘No error’)

if __name__ == «__main__»:

    main()

When we run the codes, we get the following output. The first line shows the error message, while the second line prints out more details about the error.

Exception Message -> invalid literal for int() with base 10: ‘Not a number’

Details -> (<class ‘ValueError’>, ValueError(«invalid literal for int() with base 10: ‘Not a number'»), <traceback object at 0x04F1F8C8>)

Catch-All Exception

Sometimes we want to catch any error because we cannot anticipate all the possible errors our Python program may encounter. To catch all errors, we don’t specify the type of error in the
except clause. Consider the following Python codes.

import sys

def main():

    try:

        x = int(‘Not a number’)

    except:

        print(f‘Unknown Error — {sys.exc_info()[1]}’)

        print(f‘Details — {sys.exc_info()}’)

    else:

        print(‘No error’)

if __name__ == «__main__»:

    main()

In this scenario, we need to use Python’s sys pack because out
except clause has no clue about the errors it catches. The codes generate the following output.

Unknown Error invalid literal for int() with base 10: ‘Not a number’

Details (<class ‘ValueError’>, ValueError(«invalid literal for int() with base 10: ‘Not a number'»), <traceback object at 0x04BBF800>)

Without using the
sys package

The codes above use the
sys package. Alternatively, we could show the Exception message in Python this way.

def main():

    try:

        x = int(‘Not a number’)

    except Exception as e:

        print(f‘Unknown Error — {e}’)

    else:

        print(‘No error’)

if __name__ == «__main__»:

    main()

When we don’t use the
sys package, the only way to catch all errors is utilizing the Exception in the
except clause. If we run the codes without using the mentioned package, we’ll get a similar result.

Unknown Error invalid literal for int() with base 10: ‘Not a number’

Using the sys package offers more options to programmers. For instance, we can display the details of the error. Otherwise, we only get the error messages which are sometimes not as detailed as we hope for.

And that’s how we can print exception messages and details in Python.

Got comments or suggestions?
We disabled the comments on this site to fight off spammers,
but you can still contact us via our Facebook page!.

The traceback of error generated by python interpreter can be sometimes long and not that useful. We might need to modify stack traces according to our need in some situations where we need more control over the amount of traceback getting printed. We might even need more control over the format of the trace getting printed. Python provides a module named traceback which has a list of method which let us extract error traces, format it and print it according to our need. This can help with formatting and limiting error trace getting generated. As a part of this tutorial, we’ll be explaining how we can use a different method of traceback module for different purposes. We’ll explain the usage of the method with simple examples.

There is three kinds of methods available with the traceback module.

  • print_*() — These methods are used to print stack traces to the desired output medium (standard error, standard output, file, etc).
    • print_tb()
    • print_exception()
    • print_exc()
    • print_list()
    • print_last()
    • print_stack()
  • extract_*() — These methods are used to extract stack traces from an exception and return preprocessed stack trace entries.
    • extract_tb()
    • extract_stack()
  • format_*() — These methods are used to format output generated by extract_* methods. These methods can be useful if we want to print an error stack on some GUI.
    • format_tb()
    • format_list()
    • format_exception_only()
    • format_exception()
    • format_exc()
    • format_stack()
  • walk_*() — These methods returns generator instance which lets us iterate through trace frames and print stack trace according to our need.
    • walk_stack()
    • walk_tb()

We’ll now explain the usage of these methods with simple examples one by one.

Example 1¶

As a part of our first example, we’ll explain how we can print the stack trace of error using print_tb() method.

  • print_tb(tb, limit=None, file=None) — This method accepts traceback instance and prints traces to the output. It let us limit the amount of trace getting printed by specifying limit parameter. We can give integer value to limit parameter and it’ll print trace for that many frames only. If we don’t specify a limit then by default it’ll be None and will print the whole stack trace. It has another important parameter named file which lets us specify where we want to direct output of trace to. We can give a file-like object and it’ll direct traces to it. We can also specify standard error and standard output using sys.err and sys.out as file parameters and trace will be directed to them. If we don’t specify the file parameter then by default it’ll direct trace to standard error.

Below we have artificially tried to generate an error by giving randint() method of random module negative integer numbers. We have the first printed traceback generated by the python interpreter. Then we have caught exceptions using try-except block. We have then retrieved traceback from the error object using traceback attribute of the error object and have given it to print_tb() method which prints a stack trace.

Please make a note that print_tb() only prints stack trace and does not print actual exception type.

import random

out = random.randint(-5,-10)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-a38bfad2efe7> in <module>
      1 import random
      2
----> 3 out = random.randint(-5,-10)

~/anaconda3/lib/python3.7/random.py in randint(self, a, b)
    220         """
    221
--> 222         return self.randrange(a, b+1)
    223
    224     def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type,

~/anaconda3/lib/python3.7/random.py in randrange(self, start, stop, step, _int)
    198             return istart + self._randbelow(width)
    199         if step == 1:
--> 200             raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
    201
    202         # Non-unit step argument supplied.

ValueError: empty range for randrange() (-5,-9, -4)
import traceback
import random

try:
    out = random.randint(-5,-10)
except Exception as e:
    traceback.print_tb(e.__traceback__)
  File "<ipython-input-2-200195b56950>", line 5, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))

Below we have again executed code same as the previous cell but this time we have set the limit parameter to 1 hence it only prints the first trace frame.

import traceback
import random

try:
    out = random.randint(-5,-10)
except Exception as e:
    traceback.print_tb(e.__traceback__, limit=1)
  File "<ipython-input-3-6335bba4bb4d>", line 5, in <module>
    out = random.randint(-5,-10)

Example 2¶

As a part of this example, we have explained how we can direct the trace generated to a file. We have directed the error trace generated by the code to a file named traceback_ex1.out.

import traceback
import random

try:
    out = random.randint(-5,-10)
except Exception as e:
    traceback.print_tb(e.__traceback__, file=open("traceback_ex1.out", "w"))
  File "<ipython-input-4-d02890406d60>", line 5, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))

Example 3¶

As a part of this example, we have introduced two other methods print_exception() and print_exc().

  • print_exception(exception_type, value, tb, limit=None, file=None, chain=True) — This method print exception information as well as error stack trace. We need to provide it exception type, exception value, and traceback. It’ll then print exceptions and traceback. The chain parameter is a boolean flag indicating whether we should include trace for chained exceptions or not.
  • print_exc(limit=None, file=None, chain=True) — This method whenever called will print the last exception which had happened in the program.

Please make a note that parameter limit, file, and chain are present in multiple methods of traceback module and it has the same meaning in all of them.

In this example, we have called method named exc_info() of sys module that returns tuple (exception type, exception value, exception traceback). This tuple has information about a recent exception that was caught by try-except block. We have then given this tuple to print_exception() method to print an error stack trace. We have directed stack trace to standard output in all of our examples.

Please make a note that when we used print_exception() method, it printed information about exceptions as well which was not getting printed with print_tb() method.

import traceback
import random
import sys


try:
    out = random.randint(-5,-10)
except:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print("==================Traceback 1 =========================")
    traceback.print_tb(exc_traceback, file=sys.stdout)

    print("n==================Traceback 2 ===================")
    traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stdout)

    print("n==================Traceback 3 ===================")
    traceback.print_exc(file=sys.stdout)
==================Traceback 1 =========================
  File "<ipython-input-6-bf6708f55f27>", line 7, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))

==================Traceback 2 ===================
Traceback (most recent call last):
  File "<ipython-input-6-bf6708f55f27>", line 7, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (-5,-9, -4)

==================Traceback 3 ===================
Traceback (most recent call last):
  File "<ipython-input-6-bf6708f55f27>", line 7, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (-5,-9, -4)

Example 4¶

As a part of our fourth example, we have demonstrated how we can catch the exception and print stack trace using print_exception() method. We have not retrieved exception information using sys.exc_info() this time. We have artificially generated divide by zero error in this example.

import traceback
import random

try:
    out = 10/0
except Exception as e:
    traceback.print_exception(type(e), e, e.__traceback__, file=sys.stdout)
Traceback (most recent call last):
  File "<ipython-input-7-c90920d6446e>", line 5, in <module>
    out = 10/0
ZeroDivisionError: division by zero

Example 5¶

We’ll use our fifth example to demonstrate the usage of print_last() method.

  • print_last(limit=None, file=None, chain=True) — This method prints last exception which had happened.

We have first artificially generated error and then printed the error stack by calling print_last() method.

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-8-ff29a4977585> in <module>
----> 1 out = 10/0

ZeroDivisionError: division by zero
Traceback (most recent call last):
  File "/home/sunny/anaconda3/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3418, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-8-ff29a4977585>", line 1, in <module>
    out = 10/0
ZeroDivisionError: division by zero

Example 6¶

As a part of our sixth example, we’ll demonstrate usage of extract_tb(), format_list() and print_list() methods.

  • extract_tb(tb, limit=None) — This method accepts traceback object and returns StackSummary instance. The StackSummary instance has list of FrameSummary instance where each FrameSummary instance has information about one frame of stack trace.
  • format_list(extracted_list) — This method takes as input StackSummary instance or list of FrameSummary instances as input and returns a list of strings representing stack trace.
  • print_list(extracted_list, file=None) — This method takes as input StackSummary instance or list of FrameSummary instances as input and prints stack trace.

Below we have first extracted the error stack using extract_tb() method and then printed it in different formats. We have also explained how we can use format_list() and print_list() methods. The StackSummary instance also has format() method which works exactly like format_list() method.

import traceback
import random
import sys

try:
    out = random.randint(-5,-10)
except:
    exc_type, exc_value, exc_traceback = sys.exc_info()

    traces = traceback.extract_tb(exc_traceback)

    print("Type of Traceback         : ", type(traces))
    print("Type of Individual Traces : ", type(traces[0]))

    print(" n========== Trace Format 1 ===============n")
    print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
    print("-"*100)
    for frame_summary in traces:
        print("%50s | %11s | %11d | %10s"%(frame_summary.filename, frame_summary.name, frame_summary.lineno, frame_summary.line))
        print("-"*100)

    print(" n========== Trace Format 2 ===============n")
    for trace_line in traces.format():
        print(trace_line)

    print(" n========== Trace Format 3 ===============n")
    for trace_line in traceback.format_list(traces):
        print(trace_line)

    print(" n========== Trace Format 4 ===============n")
    traceback.print_list(traces, file=sys.stdout)
Type of Traceback         :  <class 'traceback.StackSummary'>
Type of Individual Traces :  <class 'traceback.FrameSummary'>

========== Trace Format 1 ===============

                                         File Name | Method Name | Line Number |       Line
----------------------------------------------------------------------------------------------------
                   <ipython-input-10-e08cb7446344> |    <module> |           6 | out = random.randint(-5,-10)
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |     randint |         222 | return self.randrange(a, b+1)
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |   randrange |         200 | raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
----------------------------------------------------------------------------------------------------

========== Trace Format 2 ===============

  File "<ipython-input-10-e08cb7446344>", line 6, in <module>
    out = random.randint(-5,-10)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))


========== Trace Format 3 ===============

  File "<ipython-input-10-e08cb7446344>", line 6, in <module>
    out = random.randint(-5,-10)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))


========== Trace Format 4 ===============

  File "<ipython-input-10-e08cb7446344>", line 6, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))

Example 7¶

As a part of our seventh example, we’ll explain usage of methods format_tb(), format_exception() and format_exc().

  • format_tb() — This method works exactly the same as print_tb() method with the only difference that it returns a list of strings where each string is a single trace of the stack.
  • format_exception() — This method works exactly the same as print_exception() method with the only difference that it returns a list of strings where each string is a single trace of the stack.
  • format_exc() — This method works exactly the same as print_exc() method with the only difference that it returns a string that has stack trace.

Below we have explained how we can use these methods with a simple example.

import traceback
import random
import sys


try:
    out = random.randint(-5,-10)
except:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print("==================Traceback 1 =========================")
    for trace in traceback.format_tb(exc_traceback):
        print(trace)

    print("n==================Traceback 2 ===================")
    for trace in traceback.format_exception(exc_type, exc_value, exc_traceback):
        print(trace)

    print("n==================Traceback 3 ===================")
    print(traceback.format_exc())
==================Traceback 1 =========================
  File "<ipython-input-11-cd6fba9720d8>", line 7, in <module>
    out = random.randint(-5,-10)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))


==================Traceback 2 ===================
Traceback (most recent call last):

  File "<ipython-input-11-cd6fba9720d8>", line 7, in <module>
    out = random.randint(-5,-10)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)

  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))

ValueError: empty range for randrange() (-5,-9, -4)


==================Traceback 3 ===================
Traceback (most recent call last):
  File "<ipython-input-11-cd6fba9720d8>", line 7, in <module>
    out = random.randint(-5,-10)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
ValueError: empty range for randrange() (-5,-9, -4)

Example 8¶

As a part of our eighth example, we’ll demonstrate the usage of format_exception_only() method.

  • format_exception_only(exception_type, exception_value) — This method takes as input exception type and exception value. It then return list of string specifying exception description.

Below we have explained the usage of it with simple example.

import traceback
import random

try:
    out = 10/0
except Exception as e:
    for exception_line in traceback.format_exception_only(type(e), e):
        print(exception_line)
ZeroDivisionError: division by zero

Example 9¶

As a part of our ninth example, we’ll demonstrate the usage of walk_tb() and StackSummary.extract() methods.

  • walk_tb(tb) — This method takes as input the traceback instance and returns a generator that has a list of frames of the stack trace.
  • StackSummary.extract() — This method takes as input frame generator which has stack trace and generates StackSummary from it.

The StackSummary class has another method named from_list(frame_summary_list) which takes as an input list of FrameSummary instances and generates StackSummary instance from it. It can also take a list of tuples (filename, line no, name, line) as input to generate the StackSummary instance.

Below we have explained how we can generate StackSummary instance from the frame generator generated by walk_tb() method. We have then formatted stack trace as well using the StackSummary instance.

import traceback
import random
import sys

try:
    out = random.randint(-5,-10)
except Exception as e:
    tbk = e.__traceback__
    print("n==================Traceback 1 ===================n")
    for frame in traceback.walk_tb(tbk):
            print(frame)

    print("n==================Traceback 2 ===================n")
    stack_summary = traceback.StackSummary.extract(traceback.walk_tb(tbk))

    print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
    print("-"*100)

    for frame_summary in stack_summary:
        print("%50s | %11s | %11d | %10s"%(frame_summary.filename, frame_summary.name, frame_summary.lineno, frame_summary.line))
        print("-"*100)
==================Traceback 1 ===================

(<frame at 0x7faebc361248, file '<ipython-input-13-3a3aaaa264bb>', line 11, code <module>>, 6)
(<frame at 0x7faebc2e9768, file '/home/sunny/anaconda3/lib/python3.7/random.py', line 222, code randint>, 222)
(<frame at 0x7faebc2fb248, file '/home/sunny/anaconda3/lib/python3.7/random.py', line 200, code randrange>, 200)

==================Traceback 2 ===================

                                         File Name | Method Name | Line Number |       Line
----------------------------------------------------------------------------------------------------
                   <ipython-input-13-3a3aaaa264bb> |    <module> |           6 | out = random.randint(-5,-10)
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |     randint |         222 | return self.randrange(a, b+1)
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |   randrange |         200 | raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
----------------------------------------------------------------------------------------------------

Example 10¶

As a part of our tenth example, we have demonstrated the usage of print_stack() method.

  • print_stack(f=None, limit=None, file=None) — This method takes as input frame instance and prints trace back from that frame onwards.

Below we have explained how we can use print_stack() method.

import traceback
import random
import sys

try:
    out = random.randint(-5,-10)
except Exception as e:
    tbk = e.__traceback__

    while tbk:
        print("Line No : ", tbk.tb_lineno)
        #print("Frame : ", tbk.tb_frame)
        print("========== Trace ==========")
        traceback.print_stack(tbk.tb_frame, limit=1, file=sys.stdout)
        print()
        tbk = tbk.tb_next
Line No :  6
========== Trace ==========
  File "<ipython-input-14-240546dff3ae>", line 14, in <module>
    traceback.print_stack(tbk.tb_frame, limit=1, file=sys.stdout)

Line No :  222
========== Trace ==========
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)

Line No :  200
========== Trace ==========
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))

Example 11¶

As a part of our eleventh example, we have demonstrated the usage of format_stack() method.

  • format_stack(f=None, limit=None) — This method is exactly the same as print_stack() method with the only difference that it returns a list of strings instead of printing the stack trace.

Below we have explained the usage of format_stack() with a simple example that has code almost the same as print_stack() with minor changes.

import traceback
import random
import sys

try:
    out = random.randint(-5,-10)
except Exception as e:
    tbk = e.__traceback__

    while tbk:
        print("Line No : ", tbk.tb_lineno)
        #print("Frame : ", tbk.tb_frame)
        print("========== Trace ==========")
        print(traceback.format_stack(tbk.tb_frame, limit=1)[0])
        print()
        tbk = tbk.tb_next
Line No :  6
========== Trace ==========
  File "<ipython-input-15-f2267a4aafa9>", line 14, in <module>
    print(traceback.format_stack(tbk.tb_frame, limit=1)[0])


Line No :  222
========== Trace ==========
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 222, in randint
    return self.randrange(a, b+1)


Line No :  200
========== Trace ==========
  File "/home/sunny/anaconda3/lib/python3.7/random.py", line 200, in randrange
    raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))


Example 12¶

As a part of our twelfth example, we have demonstrated the usage of extract_stack() method.

  • extract_stack(f=None, limit=None) — This method works exactly print_stack() with only difference that it returns list of FrameSummary instance rather than printing stack trace.

We have explained the usage of extract_stack() with a simple example below. We can even generate StackSummary instance from the output of extract_stack() method.

import traceback
import random
import sys

try:
    out = random.randint(-5,-10)
except Exception as e:
    tbk = e.__traceback__

    print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
    print("-"*100)

    while tbk:
        trace = list(traceback.extract_stack(tbk.tb_frame, limit=1))[0]
        print("%50s | %11s | %11d | %10s"%(trace.filename, trace.name, trace.lineno, trace.line))
        print("-"*100)

        tbk = tbk.tb_next
                                         File Name | Method Name | Line Number |       Line
----------------------------------------------------------------------------------------------------
                   <ipython-input-16-181d69cd0b74> |    <module> |          14 | trace = list(traceback.extract_stack(tbk.tb_frame, limit=1))[0]
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |     randint |         222 | return self.randrange(a, b+1)
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |   randrange |         200 | raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
----------------------------------------------------------------------------------------------------

Example 13¶

As a part of our thirteenth and last example, we’ll demonstrate the usage of walk_stack() method.

  • walk_stack(f) — This method works exactly like extract_stack() method but returns generator of stack trace frames. We can generate a StackSummary instance from the output of this method.

Below we have explained the usage of the method with simple example. We have first generated StackSummary instance from the output of walk_stack() method. We have then formatted the stack trace.

import traceback
import random
import sys

try:
    out = random.randint(-5,-10)
except Exception as e:
    tbk = e.__traceback__

    print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
    print("-"*100)
    while tbk:
        stack_summary  = traceback.StackSummary.extract(traceback.walk_stack(tbk.tb_frame))

        for frame_summary in stack_summary[:1]:
            print("%50s | %11s | %11d | %10s"%(frame_summary.filename, frame_summary.name, frame_summary.lineno, frame_summary.line))
            print("-"*100)

        tbk = tbk.tb_next

                                         File Name | Method Name | Line Number |       Line
----------------------------------------------------------------------------------------------------
                   <ipython-input-17-ce4b3126d8ff> |    <module> |          13 | stack_summary  = traceback.StackSummary.extract(traceback.walk_stack(tbk.tb_frame))
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |     randint |         222 | return self.randrange(a, b+1)
----------------------------------------------------------------------------------------------------
     /home/sunny/anaconda3/lib/python3.7/random.py |   randrange |         200 | raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
----------------------------------------------------------------------------------------------------

This ends our small tutorial explaining the usage of the traceback module. Please feel free to let us know your views in the comments section.

Sometimes, a Python script comes across an unusual situation that it can’t handle, and the program gets terminated or crashed. In this article, we’ll learn How to catch and print the exception messages in python. If you want to learn more about Python Programming, visit Python Tutorials.

The most common method to catch and print the exception message in Python is by using except and try statement. You can also save its error message using this method. Another method is to use logger.exception() which produces an error message as well as the log trace, which contains information such as the code line number at which the exception occurred and the time the exception occurred.

The most common example is a “FileNotFoundError” when you’re importing a file, but it doesn’t exist. Similarly, dividing a number by zero gives a “ZeroDivisionError” and displays a system-generated error message. All these run-time errors are known as exceptions. These exceptions should be caught and reported to prevent the program from being terminated.

In Python, exceptions are handled with the (try… except) statement. The statements which handle the exceptions are placed in the except block whereas the try clause includes the expressions which can raise an exception. Consider an example in which you take a list of integers as input from the user.

Example

# Creating an empty list
new_list =[]

n = int(input("Enter number of elements : "))

for i in range(n):

    item = int(input())

    # Add the item in the list
    new_list.append(item)

print(new_list)

The program shown above takes integers as input and creates a list of these integers. If the user enters any character, the program will crash and generate the following output.

Output:

Enter number of elements : 7
23
45
34
65
2a
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-ac783af2c9a3> in <module>()
      3 n = int(input("Enter number of elements : "))
      4 for i in range(n):
----> 5     item = int(input())
      6     # Add the item in the list
      7     new_list.append(item)

ValueError: invalid literal for int() with base 10: '2a'

USE except and try statement to CATCH ANd print the EXCEPTION AND SAVE ITS ERROR MESSAGEs

The first method to catch and print the exception messages in python is by using except and try statement. If the user enters anything except the integer, we want the program to skip that input and move to the next value. In this way, our program will not crash and will catch and print the exception message. This can be done using try and except statements. Inside the try clause, we’ll take input from the user and append it to “new_list” variable. If the user has entered any input except integers mistakenly, the except block will print “Invalid entry” and move towards the next value. In this way, the program continues to run and skip the invalid entries.

# Creating an empty list
new_list =[]

n = int(input("Enter number of elements : "))

for i in range(n):

  try:
    item = int(input())

    # Add the item in the list
    new_list.append(item)

  except:

    print("Invalid Input!")

    print("Next entry.")

print("The list entered by user is: ", new_list)

Output:

Enter number of elements : 7
65
43
23
4df
Invalid Input!
Next entry.
76
54
90
The list entered by user is:  [65, 43, 23, 76, 54, 90]

There are various methods to catch and report these exceptions using try and except block. Some of them are listed below along with examples.

Catching and reporting/Print exceptions messages in python

This is the second method to catch and print the exception messages in python. With the help of the print function, you can capture, get and print an exception message in Python. Consider an example in which you have a list containing elements of different data types. You want to divide all the integers by any number. This number on division with the string datatypes will raise “TypeError” and the program will terminate if the exceptions are not handled. The example shown below describes how to handle this problem by capturing the exception using the try-except block and reporting it using the print command.

EXAMPLE 3:

list_arr=[76,65,87,"5f","7k",78,69]

for elem in list_arr:

  try:

    print("Result: ", elem/9)

  except Exception as e:

    print("Exception occurred for value '"+ elem + "': "+ repr(e))

Output:

Result:  8.444444444444445
Result:  7.222222222222222
Result:  9.666666666666666
Exception occurred for value '5f': TypeError("unsupported operand type(s) for /: 'str' and 'int'")
Exception occurred for value '7k': TypeError("unsupported operand type(s) for /: 'str' and 'int'")
Result:  8.666666666666666
Result:  7.666666666666667

using try and logger.exception to print an error message

Another method is to use logger.exception() which produces an error message as well as the log trace, which contains information such as the code line number at which the exception occurred and the time the exception occurred. This logger.exception() method should be included within the except statement; otherwise, it will not function properly.

import logging

logger=logging.getLogger()

num1=int(input("Enter the number 1:"))

num2=int(input("Enter the number 2:"))

try: 

  print("Result: ", num1/num2)

except Exception as e:

  logger.exception("Exception Occured while code Execution: "+ str(e))

Output:

Enter the number 1:82
Enter the number 2:4
Result:  20.5

Suppose if a user enters 0 in the 2nd number, then this will raise a “ZeroDivisionError” as shown below.

Enter the number 1:9
Enter the number 2:0
Exception Occured while code Execution: division by zero
Traceback (most recent call last):
  File "<ipython-input-27-00694f615c2f>", line 11, in <module>
    print("Result: ", num1/num2)
ZeroDivisionError: division by zero

Similarly, if you’ve two lists consisting of integers and you want to create a list consisting of results obtained by dividing list1 with list2. Suppose you don’t know whether the two lists consist of integers or not.

EXAMPLE 5:

import logging

logger=logging.getLogger()

list1=[45, 32, 76, 43, 0, 76]

list2=[24, "world", 5, 0, 4, 6]

Result=[]

for i in range(len(list1)):

  try:

    Result.append(list1[i]/list2[i])

  except Exception as e:

    logger.exception("Exception Occured while code Execution: "+ str(e))

print(Result)

Output:

In this example, “world” in the 2nd index of list2 is a string and 32 on division with a string would raise an exception. But, we have handled this exception using try and except block. The logger.exception() command prints the error along with the line at which it occurred and then moves toward the next index. Similarly, all the values are computed and stored in another list which is then displayed at the end of the code.


Exception Occured while code Execution: unsupported operand type(s) for /: 'int' and 'str'
Traceback (most recent call last):
  File "<ipython-input-1-5a40f7f6c621>", line 8, in <module>
    Result.append(list1[i]/list2[i])
TypeError: unsupported operand type(s) for /: 'int' and 'str'
Exception Occured while code Execution: division by zero
Traceback (most recent call last):
  File "<ipython-input-1-5a40f7f6c621>", line 8, in <module>
    Result.append(list1[i]/list2[i])
ZeroDivisionError: division by zero
[1.875, 15.2, 0.0, 12.666666666666666]

The logger module has another function “logger.error()” which returns only an error message. The following example demonstrates how the logger.error() function may be used to capture exception messages in Python. In this example, we have just replaced logger.exception in the above example with logger.error() function

EXAMPLE 6:

import logging

logger=logging.getLogger()

list1=[45, 32,76,43,0, 76]

list2=[24, "world", 5, 0, 4, 6]

Result=[]

for i in range(len(list1)):

  try:

    Result.append(list1[i]/list2[i])

  except Exception as e:

    logger.error("Exception Occured while code Execution: "+ str(e))

print(Result)

Output:

Exception Occured while code Execution: unsupported operand type(s) for /: 'int' and 'str'
Exception Occured while code Execution: division by zero
[1.875, 15.2, 0.0, 12.666666666666666]

Catching and printing Specific Exceptions messages

The previous section was all about how to catch and print exceptions. But, how will you catch a specific exception such as Valueerror, ZeroDivisionError, ImportError, etc? There are two cases if you want to catch one specific exception or multiple specific exceptions. The following example shows how to catch a specific exception.

EXAMPLE 7:

a = 'hello'

b = 4

try:

    print(a + b)

except TypeError as typo:

    print(typo)

Output:

can only concatenate str (not "int") to str

Similarly, if you want to print the result of “a/b” also and the user enters 0 as an input in variable “b”, then the same example would not be able to deal with ZeroDivisionError. Therefore we have to use multiple Except clauses as shown below.

EXAMPLE 8:

a = 6

b = 0

try:

    print(a + b)

    print(a/b)

except TypeError as typo:

    print(typo)

except ZeroDivisionError as zer:

    print(zer)

Output:

The same code is now able to handle multiple exceptions.

6
division by zero

To summarize, all of the methods described above are effective and efficient. You may use any of the methods listed above to catch and print the exception messages in Python depending on your preferences and level of comfort with the method. If you’ve any queries regarding this article, please let us know in the comment section. Your feedback matters a lot to us.

Понравилась статья? Поделить с друзьями:
  • Get error reporting php
  • Get error message php
  • Get error end of file resetting in 5 seconds bminer
  • Get error codes
  • Get error code java