printing error message from an Exception

M

mark jason

hi
I was trying out some file operations and was trying to open a non
existing file as below

def do_work(filename):
try:
f = open(filename,"r");
print 'opened'
except IOError, e:
print 'failed',e.message
finally:
f.close()
print 'closed'

if __name__=='__main__':
do_work("C:\code\misc.txt") # there is no such file

I am getting an error and a warning

DeprecationWarning: BaseException.message has been deprecated as of
Python 2.6
print 'failed',e.message

UnboundLocalError: local variable 'f' referenced before assignment

Is there a way to overcome the DeprecationWarning? I wanted to print
the error message from the IOError.How do I do this?
Also ,what should I do about the UnboundLocalError?

thanks and regards ,
mark
 
S

Steven D'Aprano

hi
I was trying out some file operations and was trying to open a non
existing file as below

def do_work(filename):
try:
f = open(filename,"r");
print 'opened'
except IOError, e:
print 'failed',e.message
finally:
f.close()
print 'closed'


The problem is, you try to close a file that not only hasn't been opened,
but the name f isn't bound to a value:
failed
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in do_work
UnboundLocalError: local variable 'f' referenced before assignment


if __name__=='__main__':
do_work("C:\code\misc.txt") # there is no such file

I am getting an error and a warning

DeprecationWarning: BaseException.message has been deprecated as of
Python 2.6
print 'failed',e.message

UnboundLocalError: local variable 'f' referenced before assignment

Is there a way to overcome the DeprecationWarning? I wanted to print the
error message from the IOError.How do I do this?

Generally, the best way to print error messages is to print the *entire*
error message, including the traceback. You do that by just not catching
the exception at all.

But for the times you do need to do something else with the exception,
instead of exception.message, look at exception.args. This will be a
tuple of one or more items, the first item should be the error message.

Also ,what should I do about the UnboundLocalError?

Use finally for things which must be done regardless of whether or not
the previous operation succeeded, not for things that should only be done
if the previous operation succeeded but not if it failed.

def do_work(filename):
try:
f = open(filename,"r");
print 'opened'
except IOError, e:
# By the way, IOError is not the only exception you could see.
print 'failed', e.args
else:
f.close()
print 'closed'


Or, slightly more useful:

def do_work(filename):
s = ''
try:
f = open(filename,"r");
print 'opened'
except IOError, e:
# By the way, IOError is not the only exception you could see.
print 'failed', e.args
else:
try:
s = f.read()
finally:
f.close()
print 'closed'
print s
 
M

mark jason

    # By the way, IOError is not the only exception you could see.


thanks for the help Steven. Is it OK to catch Exception instead of
IOError ?
In some operation which can cause many errors ,can I use the
following?

try:
do_something()
except Exception,e:
display_message(e.args)
handle_exception(e)


thanks,
mark
 
P

Peter Otten

mark said:
hi
I was trying out some file operations and was trying to open a non
existing file as below

def do_work(filename):
try:
f = open(filename,"r");
print 'opened'
except IOError, e:
print 'failed',e.message
finally:
f.close()
print 'closed'

if __name__=='__main__':
do_work("C:\code\misc.txt") # there is no such file

I am getting an error and a warning

DeprecationWarning: BaseException.message has been deprecated as of
Python 2.6
print 'failed',e.message

UnboundLocalError: local variable 'f' referenced before assignment

Is there a way to overcome the DeprecationWarning? I wanted to print
the error message from the IOError.How do I do this?
Also ,what should I do about the UnboundLocalError?

You are mixing two things here:

(1) print an error message when the file cannot be opened
(2) ensure that the file will always be closed

If you attack both aspects separately they become simpler:

# 1
try:
f = open(...)
except IOError as e:
print "Failed", e

# 2a
f = open(...)
try:
print "opened"
finally:
f.close()

which can be simplified to

# 2b
with open(...) as f:
print "opened"

Putting 1 and 2b together:

try:
with open(...) as f:
print "opened"
except IOError as e:
print "Failed", e

There is a disadvantage though: an IOError that is raised in the with-suite
will also be caught. If you're concerned about that you can use:

try:
f = open(...)
except IOError as e:
print "Failed", e
else:
with contextlib.closing(f):
print "opened"
 
J

Jean-Michel Pichavant

mark said:
thanks for the help Steven. Is it OK to catch Exception instead of
IOError ?
In some operation which can cause many errors ,can I use the
following?

try:
do_something()
except Exception,e:
display_message(e.args)
handle_exception(e)


thanks,
mark
You shouldn't.

If you want to handle an exception, you need to know about it. What if
your handle_exception meets some exception it does not know how to handle ?

People are sometimes using bare try except clause to say 'look ! my
function never crash !'. True but it usually has an unpredictable
behavior upon exception being raised, and that is much worse that a
clean uncought exception.


What you can do :

try:
do_something()
except IOError:
# handler IOerror
except KeyboardInterrupt:
print 'stopping...'
sys.exit(0)
except NotImplementedError:
# handler missing implementation

Everything else should be kept uncought.

JM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top