Getting exception details in Python

54,667

Solution 1

You can use sys.exc_info to get information about the exception currently being handled, including the exception object itself. An IOError exception contains all of the information you need, including the filename, the errno, and a string describing the error:

import sys

try:
    f1 = open('example1')
    f2 = open('example2')
except IOError:
    type, value, traceback = sys.exc_info()
    print('Error opening %s: %s' % (value.filename, value.strerror))

Execution in the try block will obviously still halt after the first exception.

Solution 2

Use the traceback module:

traceback.print_exc()

Solution 3

When using exc_type, value, exc_traceback = sys.exc_info(), note that the filename that generated the exception can be obtained through the following:

exc_traceback.tb_frame.f_locals.get('filename')

Solution 4

You mention using a loop, but you're not actually using a loop. Use a loop. That way you can write each file, one at a time, inside a single try block. You don't appear to be doing anything with the files except write one value to each, so you don't need to keep them all open.

for filename in ['file1.txt', 'file2.txt', ...]:
    try:
        with open(filename, 'w+') as f:
            f.write(str(a)+"whatever")
    except IOError:
        print("Error occurred with", filename)

Edit: If you have wildly different things to write to the different files, create a dictionary or other data structure ahead of time storing the mapping between files and data, then use that in the loop.

data = {'file1.txt': str(a), 'file2.txt': 'something else', 'file3.txt': str(a)+str(b)}

for filename, output in data.items():
    try:
        with open(filename, 'w+') as f:
            f.write(output)
    except IOError:
        print("Error occurred with", filename)
Share:
54,667
user891876
Author by

user891876

Updated on January 16, 2020

Comments

  • user891876
    user891876 over 4 years

    I have to open & write to about 10 different files all within the same loop. e.g:

    for i in range(0,10):
        try:
            a=5
            file1 = open("file1.txt",'w+')
            file2 = open("file2.txt",'w+')
            #... etc
    
            print(str(a),file=file1)
            print(str(a)+"hi",file=file2)
            # ... etc
        except: 
            #error handling
    

    Now what I'd like to do is be able to get specific exception information such as what file was being opened/written to within the general exception. From my current understanding, I'd have to do something like this to achieve what I want:

    for i in range(0,5):
        a=5
        try:
            file1 = open("file1.txt",'w+')
            print(str(a),file=file1)
        except: 
            #error handling for file1
        try:
            file2 = open("file2.txt",'w+')
            print(str(a)+"hi",file=file2)
        except: 
            #error handling for file2
    

    ...Which is going to get extremely clunky and unattractive when I have to do this for about 10 different files. Is there any way to get (for example) the filename info out of a general exception like in my first example? Basically so the exception could report things like "error when writing to file1" without a try/except specifically for file1 operations.

    edit: This is a massive over-simplification of the data being written to the file. str(a) and str(a)+"hi" are not really good representations of the data actually being written; file1 may need a hardcoded integer, where file2 may need a string formatted with multiple variables. to generalize the opening/writing process into a loop isn't going to work very nicely.