1
votes

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?

4
It's not "uncatchable", it's the csv module that's raising the error. - MattH
Are they ANY un-catchable exceptions in Python? - James Brooks
The reader method is in a compiled c module. Strip the nulls from your input before pushing it through csv.reader. Are there supposed to be nulls in your input data? - MattH

4 Answers

7
votes

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.

4
votes

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.

0
votes

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.

0
votes

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'