[Python-ideas] Catching of multiple exceptions without halting execution

Masklinn masklinn at masklinn.net
Mon Jun 24 21:48:20 CEST 2013


On 2013-06-24, at 21:13 , Samuel Littley wrote:

> I find I often have to run several tests on data input, making a list of
> which tests succeed, which fail, and somehow determine where to go after
> running all the tests. Obviously, the standard way of showing that a
> test as failed is to raise an exception, caught by try/except/finally,
> however this would only allow one test to be flagged as failing,
> requiring multiple runs to correct every fault that may exist.
> 
> I propose an alternative to try/except, as follows:
> 
> validate:
>    // Code to run tests, raising exceptions if tests fail
> accept:
>    // Code to run if all tests pass (i.e. no exceptions)
> reject es:
>    // Code to handle each failed test
> except:
>    // Code to handle non-test related exceptions
> finally:
>    // Code to be always executed 
> 
> The difference to a normal try/except is a different type of exception,
> which, rather than halting execution, is added to the list `es`, which
> the reject block could then loop through to display error messages,
> require re-entry, etc. Standard exceptions could be raised and caught by
> the except block. Alternatively, the except block could not be a part of
> this, and instead all exceptions are caught in the reject block, which
> could then raise exceptions itself to be caught by a try/except/finally
> around the validate/accept/reject/finally
> 
> The use case I thought of is validating data entry (from web forms for
> example), where each exception creates an error message displayed on the
> form, however I'm pretty sure there would be other uses for this.

Why not something along the lines of:

    errors = # validation code()
    if not errors:
        # no problem
    else:
        # problems

? An other option if the validation system has significant stack depth
is to pass in an error handler callback as parameter (note: no matter
how good it looks at first glance, I strongly recommend not using
warnings.catch_warnings, it's fairly brittle and not thread-safe)

Exceptions are a tool, not the only one.

Although if you still *want* an exception-type system, I'd suggest
considering the extension of exceptions into Signals[0]/Conditions[1]
(as in Smalltalk or Common Lisp) instead:

    try:
        validate_stuff()
    except (ASignal, AnOtherSignal):
        # handle test failure
        resume # tells validation to keep running
    except:
        # usual fatal errors
    finally:
        # keep running

(note: success is domain-dependent and should be handed through
interactions of the various blocks: some tests failing may not be an
issue, or the system may still be considered successful under a certain
failure threshold, …)

I believe this is a more general concept, a rather natural (if there's
such a thing) super-set of existing exceptions and an already known
and studied solution to the issue. It can also be used to solve a number
of other problems.

[0] http://www.gnu.org/software/smalltalk/manual/html_node/Handling-exceptions.html#Handling-exceptions
    http://live.exept.de/doc/online/english/programming/exceptions.html
[1] http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html


More information about the Python-ideas mailing list