OOP - how to abort an __init__ when the initialisation code fails ?

Oscar Benjamin oscar.j.benjamin at gmail.com
Wed Nov 6 12:13:57 EST 2019


On Tue, 5 Nov 2019 at 21:52, Gregory Ewing <greg.ewing at canterbury.ac.nz> wrote:
>
> Peter J. Holzer wrote:
> > On 2019-11-04 18:18:39 -0300, Luciano Ramalho wrote:
> >
> > Or maybe don't catch it here at all but just let it bubble up until it
> > hits a level where dealing with it makes sense from the user's point of
> > view
>
> Often it makes sense to do both -- catch the exception and
> re-raise it with a more informative error message, e.g.
>
>       try:
>           with open(filename, "w") as f:
>               f.write("some")
>               f.write("data")
>       except OSError as e:
>           raise OSError("Couldn't write fibble data to %s: %s" % (filename, e))
>
> That way you don't get frustrating Microsoft style error
> messages which say "The system could not open the specified file"
> while giving no clue about *which* file was specified... aarggh!

Of course it doesn't apply to simples cases like above but my
experience of catching and reraising is that it often is the *cause*
of those kind of uninformative or even misleading error messages. In
Python the original exception message plus traceback is often very
informative (to a programmer!) about the problem. Catching and
reraising can mean that you end up crafting an error message somewhere
higher up where the filename isn't known any more. Even worse is if
the author's assumption about the source of the exception is
incorrect.

The problem with trying to specify how much should go into a try block
is that one line can be thousands of lines if it calls a function that
calls another function and so on. Even if you have a very narrow
lexical scope for the try block it can still cover the whole of your
codebase (or even that of all the dependencies you use) so the danger
of overly broad exception handling can not be understood in such
simple terms.

One thing that is clear though is that you should catch the most
specific kind of exception possible. Ideally if the exception is
raised in your code then it should be a dedicated exception class. If
that exception is only raised in one specific place I see nothing
wrong with wrapping all of your code in a try/except that catches that
one exception: when the exception is caught you know exactly why and
can handle appropriately.

Oscar


More information about the Python-list mailing list