The Right Approach to Exceptions
H. S. Teoh
hsteoh at quickfur.ath.cx
Mon Feb 20 11:34:48 PST 2012
On Mon, Feb 20, 2012 at 08:11:28PM +0100, deadalnix wrote:
> Considering the handler, This would be great to see it as scoped.
> This imply using a scope delegate, and probably something as RAII to
> create it and delete it when we go out of scope.
Yeah, that definitely should be done, otherwise a handler installed by a
function that's no longer in scope will still kick in when the same
exception is triggered by unrelated code. That would be very bad.
> I'm more doubtfull about what can be done on the throw side. This need
> to be refined, and to be honnest, the idea is too new in my head to
> come up with something significant. The concept needs some
> I wonder however, how to do something clean. The delegate will need
> some knowledge of the thrower onternal to do something really usefull,
> but then, we make the codebase more fragile (because the caler will
> depend on implementation of the calee, something that we want to
I've tried to do this by encapsulating the recovery options in the
Condition object. So the delegate knows, here are the options I have of
recovering, but it doesn't need to know how the low-level function
implements those recovery strategies.
For example, the FileNotFoundCond object has a restart() method, and an
inherited abort() method. So these are the options available to the
delegate. These methods just return an opaque object to the recovery
system, which passes it to the low-level function. Then the low-level
function tries to recover according to which object it receives. So the
delegate doesn't actually know how each option is implemented, it just
knows these are available options to recover.
Also, the restart() method takes a new filename as parameter, so the
delegate even knows what data is needed to provide to a particular
recovery option in order to help the low-level function recover.
Of course, the current implementation is very skeletal, and there are
still many open issues:
- How does the delegate know *which* low-level function throws a
particular Condition? For example, what if main() calls some function
that calls openDataFile() many times? What if openDataFile() is called
at different points in the function call hierarchy? How does the
delegate know which recovery choice is appropriate for every
FileNotFoundCond() that it catches?
- Every Condition the program might encounter requires a lot of code:
you need to define a Condition subclass, populate it with recovery
strategies, and then have the throwing code check and handle each
option. Is there a way to reduce the amount of code you need to write
for every Condition?
- Also, Conditions seem to specific to a particular situation. It's not
too bad for generic problems like FileNotFoundCond; we know what it
means when the OS says "file not found", and we generally know what
can be done to fix that. But what about ParseErrorCond? The delegate
would need to know what kind of parse error, or even which parser
issued that error, otherwise how would it know how to correct the
But this means that every different parser in the program will require
its own ParseError subclass, along with the associated recovery
options. Seems like a lot of work for only occasional benefit.
- Are there general recovery options that apply generally across the
majority of Conditions? If so, we can alleviate delegates from having
to know the intimate details of a particular operation, which
introduces too much coupling between high-level and low-level code.
A more minor issue is that the current implementation is not very well
written. :) I'll have to think about this more, to know how to better
implement it. But I wanted to get the semantics of it out first, so that
at least we can start discussing the conceptual aspects of the idea.
They say that "guns don't kill people, people kill people." Well I think
the gun helps. If you just stood there and yelled BANG, I don't think
you'd kill too many people. -- Eddie Izzard, Dressed to Kill
More information about the Digitalmars-d