views:

90

answers:

4

The issue came up in this question, which I'll recapitulate in this code:

import csv
FH = open('data.csv','wb')
line1 = [97,44,98,44,99,10]
line2 = [100,44,101,44,102,10]
for n in line1 + line2:
    FH.write(chr(n))
FH.write(chr(0))
FH.close()

import _csv

FH = open('data.csv')
reader = csv.reader(FH)
for line in reader:
    if '\0' in line:  continue
    if not line:  continue
    try:
        print line
    except _csv.Error:
        print 'error'

Run it:

$ python test.py 
['a', 'b', 'c']
['d', 'e', 'f']
Traceback (most recent call last):
  File "test.py", line 14, in <module>
    for line in reader:
_csv.Error: line contains NULL byte

So, I guess the inclusion of NUL in the file causes an "uncatchable" exception.

The question is, besides sanitizing the file first, what's the best way of dealing with this? How common are "uncatchable" exceptions?

+5  A: 

You are not putting the "try" block at the right place to catch this exception. In other words, this exception is "catchable", just revisit the question you have referenced.

The traceback clearly states that the problem is on the line with the "for" statement.

jldupont
A: 

The code that's throwing the exception isn't inside a try/except.

Traceback (most recent call last):
  File "test.py", line 14, in <module>
    for line in reader:

Just like the traceback shows, retrieving the next line from reader is what's causing the exception. You need to have the entire for inside a try.

jamessan
A: 

Try this :

FH = open('data.csv')
try:
    reader = csv.reader(FH)
    for line in reader:
        if '\0' in line:  continue
        if not line:  continue
            print line
except _csv.Error:
    print 'error'
Bluebird75
+2  A: 

It's not uncatchable, you're just trying to catch it in the wrong place. The error is occurring in the line:

for line in reader:

and you are putting your try block around:

print line

The exception has already been raised at this point.

You could wrap the entire block as shown in other answers, or isolate the exception by warping the loop to manually manipulate the iteration of your csv reader:

while 1:
    try:
        line = f.next()
    except StopIteration:
        break
    except csv.Error:
        print "Error occurred"
    process_line(line)

This hurts readability in favor of limiting your exception handling to the relevant bit of code. Probably overkill with an exception as specific as csv.error, but it's a handy technique when trying to isolate, for instance, an IOError.

jcdyer