52

I'm trying to read all files from a folder that matches a certain criteria. My program crashes once I have an exception raised. I am trying to continue even if there's an exception but it still stops executing.

This is what I get after a couple of seconds.

error <type 'exceptions.IOError'>

Here's my code

import os 
path = 'Y:\\Files\\'
listing = os.listdir(path)
try:
    for infile in listing:
        if infile.startswith("ABC"):
            fo = open(infile,"r")
            for line in fo:
                if line.startswith("REVIEW"):
                    print infile
            fo.close()
except:
    print "error "+str(IOError)
    pass
Ank
  • 6,040
  • 22
  • 67
  • 100
  • 2
    "I am trying to continue even if there's an exception"- never do this unless you have a clear plan for how your program should continue. Assuming that your code after the except: block relies on the file contents, continuing on after an IO error is a bad idea. Let the exception crash the program instead, so that you can actually notice and fix the underlying problem. – musical_coder Sep 25 '13 at 00:52
  • Beside the point, but [a bare `except` is bad practice](/q/54948548/4518341). Instead, use the specific exception you're expecting like `except IOError`, or at least `except Exception`. – wjandrea Aug 11 '22 at 17:34

4 Answers4

66

Put your try/except structure more in-wards. Otherwise when you get an error, it will break all the loops.

Perhaps after the first for-loop, add the try/except. Then if an error is raised, it will continue with the next file.

for infile in listing:
    try:
        if infile.startswith("ABC"):
            fo = open(infile,"r")
            for line in fo:
                if line.startswith("REVIEW"):
                    print infile
            fo.close()
    except:
        pass

This is a perfect example of why you should use a with statement here to open files. When you open the file using open(), but an error is catched, the file will remain open forever. Now is better than never.

for infile in listing:
    try:
        if infile.startswith("ABC"):
            with open(infile,"r") as fo
                for line in fo:
                    if line.startswith("REVIEW"):
                        print infile
    except:
        pass

Now if an error is caught, the file will be closed, as that is what the with statement does.

TerryA
  • 58,805
  • 11
  • 114
  • 143
11

Move the try/except inside the for loop. Like in:

  import os 
    path = 'C:\\'
    listing = os.listdir(path)
    for infile in listing:
        try:    
            if infile.startswith("ABC"):
                fo = open(infile,"r")
                for line in fo:
                    if line.startswith("REVIEW"):
                        print infile
                fo.close()
        except:
              print "error "+str(IOError)
Rami
  • 7,162
  • 1
  • 22
  • 19
10

You're code is doing exactly what you're telling it to do. When you get an exception, it jumps down to this section:

except:
    print "error "+str(IOError)
    pass

Since there's nothing after that, the program ends.

Also, that pass is superfluous.

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • 3
    @Ankur `pass` means "do nothing". Your code will continue without it. The problem is that there's nothing for it to do after your `except` block. – Brendan Long Sep 25 '13 at 00:37
1

As per strictest interpretation of the question "continue even if there's an exception". Python gives us a keyword "finally" which executes a block of code no matter what precedes it. The only issue with this method will run a block of code regardless of the type of error, which might not be desirable for all cases.

try:
  unreal = 3/0 # raises divide by zero exception
  print(unreal)

# handles zerodivision exception
except :
  print("Can't divide by zero, 0 has no multiplicative inverse")

finally:
# this block is always executed
  print("Brahmagupta claimed that “zero divided by a zero is zero.”) 
Jose Urena
  • 59
  • 1
  • 3