[Tutor] Terminology question

Steven D'Aprano steve at pearwood.info
Sat May 16 07:45:17 CEST 2015


On Fri, May 15, 2015 at 12:02:44PM -0700, Jim Mooney Py3.4.3winXP wrote:
> On 14 May 2015 at 16:47, Alan Gauld <alan.gauld at btinternet.com> wrote:
> 
> > Rather than printing the messages you could re-raise
> > the error but with the error message attached as a string.
> >
> 
> I'm a little unclear how you catch the string you create in a raise, in the
> caller. I tried an example from the docs but it didn't work.

What does "didn't work" mean? Did your computer crash? Catch fire? A 
completely different error got printed? Something else?


> Could you
> provide a simple example? Sometimes the docs are heavy slogging if you
> don't already know what's what ;')

I'm not entirely sure what part you are having trouble with. I assume 
you know how to catch an exception:

alist = []
try:
    value = alist[2]
except IndexError:
    pass  # Just pretend it didn't happen...


and how to inspect its error message:



alist = []
try:
    value = alist[2]
except IndexError as err:
    print(err.args[0])



We can also *replace* the error message with one of our own. The args 
attribute is a tuple, normally the error message is in the zeroeth 
position as above. So we just have to replace args with a tuple of our 
own and re-raise the exception:


try:
    value = alist[2]
except IndexError as err:
    err.args = ("Er, wot?",) + err.args[1:]
    raise



An alternative is to replace the exception with a completely different 
exception:



try:
    value = alist[2]
except IndexError:
    raise RuntimeError("er, wot?")



In Python 2, this suppresses the IndexError and raises RuntimeError 
instead. However, this hides bugs in the case that the second exception 
isn't deliberate, but a bug. So starting with Python 3, exceptions are 
chained, which means that if an exception occurs inside an "except" 
block, Python will display both exceptions and not just the most recent:


Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: er, wot?



This is a great boon for debugging accidental bugs, but doesn't help 
much if you actually do intend to replace one exception with another. So 
starting from Python 3.3 you can suppress the chaining:

try:
    value = alist[2]
except IndexError:
    raise RuntimeError("er, wot?") from None



which gives just a single exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: er, wot?



Does this help?




-- 
Steve


More information about the Tutor mailing list