[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