[
Lists Home |
Date Index |
Thread Index
]
* Peter Hunsberger <peter.hunsberger@gmail.com> [2005-01-05 10:27]:
> On Tue, 4 Jan 2005 22:45:22 -0500, Alan Gutierrez
> <alan-xml-dev@engrm.com> wrote:
> > * Karl Waclawek <karl@waclawek.net> [2005-01-04 19:30]:
> > >
> > >
> > > Alan Gutierrez wrote:
>
> <snip>lot's of details on error handling I haven't been following very
> well</snip>
>
> > That's hard. What behavior is common to all error handling?
> >
> > I'd like to know, really, because I'd like to take some time to
> > develop some error handling best practices, and perhaps, and
> > error event library is a project in itself.
> >
> > Uche, in a other thread, broke down handling, as pass, fail,
> > log, or fix. For pass, fail/raise, and log, one can probably
> > provide default implmentations, and dispatch them based on
> > pattern matching.
> >
> > This exception class, raised by this handler, log and fail.
> >
> > Oh, I guess, with an interface as simple as this.
> >
> > public interface StrategyCassandra {
> > public void error(StrategyError strategyError);
> > }
> >
> > At some point I was expecting to see the fixes written out in
> > the error method, so the interface name is now a misnomer.
> >
> > The object will not always be a Cassandra.
> >
> > public interface ErrorResponder {
> > public void error(Event event, StrategyError error);
> > }
> >
> > Then you get this implementation, which oddly takes the place of
> > a catch block.
> >
> > public class ErrorDispatcher implements ErrorResponder {
> > public void forError(ErrorResponder response);
> > public void forError(Class exceptionType, ErrorRepsonder response);
> > public void forErrors(Class[] exceptionTypes, ErrorRepsonder response);
> > }
> >
> > The error method could return boolean, and that is checked to
> > see if the error was handled. Or maybe the StrategyError has a
> > retry method.
>
> I wish I had time to take in everything you've been bouncing back and
> forth here. It's a little unusual for xml-dev but it appears to apply
> to much of what we are doing. The reason why I'm commenting here is
> that the above caught my eye and -- without really understanding the
> whole issue -- suggests that you might have a inversion of control
> (IOC) pattern that often shows up in frameworks?
Yup. Yup.
Thanks for reminding me. I'd forgotten about all that IOC
reading I'd done earlier in this year.
I helps the discussion. Talking about it in terms of IoC might
cut through the, "Well, are your excpetions checked, or
unchecked? Because unchecked exceptions are bad." stage of an
error handling disucssion.
I'm finding that many Java programmers have an exceptoin
strategy that goes like so:
1) Declare checked exception.
2) ?
3) Profit!
Not on this list, but elsewhere.
> If so, I'm guessing, you might explore using the Exception or Error
> itself to encapsulate much of the details on how to handle itself. In
> our case we do something like:
> public class XXException extends Exception {
> public final int DBG = -1;
> public final int MSG = 0;
> public final int WNG = 2;
> public final int ERR = 3;
> private int highestLevel = DBG;
> private Vector msgV = null; // Map could be cleaner but more work...
>
[snip]
> public void test( int level ) throws XXException {
> if ( msgV.size() > 0 && highestLevel >= level )
> throw this;
> }
[snip]
Interesting. A severity flag.
> }
>
> // Create an SAX stream for the output messages
> public void generateSaxMsgs( XMLConsumer xmlConsumer, String
> namespace, String prefix ) {
Are you indicating here, that one option is to stream the error
report to the next handler? That's common in what I'm doing.
Clever.
> }
> The things here that I suspect might be relevant to your discussion are:
> 1) you can pass one of these beasts around as an accumulator, the
> game's not over on the first error. In particular, the vector wouldn't
> have to be straight Strings;
I keep a stack of "state of procesing" objects in a SAX
Content/LexicalHandler.
The Content/LexicalHandler is a Fascade to a Composition of
event processing Strategies which Decorate and Delegate.
(Strategies can hand off control to other strategies, for a
any sub-tree. A Strategy could hand off a sub-tree to
document builder Strategy. The document is returned to the
delegating Strategy when when the endElement event occurs.
Hence the stack.)
This state of processing object is where I'd put two chains of
objects.
~ ErrorResponder
- This is called to allow client code the opporuntiy to
respond to an exceptional condition before it is
thrown and processing is aborted. The error responder
can ignore, raise, suspend processing, log, or fix for
retry. (Suspend processing means to ignore the events
until we return a place were we can continue.)
~ ThrowResponder
- These are registered by participents withing the
SAX Content/LexicalHandler to restore state if an
event is thrown.
! IoC exception handling.
I feel that the chaining and accumulation, can be done through
composition of the ErrorRepsonder interface. Which is:
public interface ErrorResponder {
public void error(Context context, Event event, StrategyError error)
throws SomeSortOfException {
}
}
You can have a DispatchingErrorResponder, or an ErrorResponderList,
and so on.
> 2) it knows how to test itself for certain situations, you can have
> additional methods for other situations and the details of what to do
> for each case might be built in;
That's hard. I'd like to provide an object like the one you
described, but I would make it final, and spare. I'd compose
error handling logic using the responders.
/* Image the method bodies, please. Flip any one breaker,
* and the other breakers raise and IllegalStateException(). */
public final class StrategyError extends (Runtime)?Exception {
public StrategyError(Throwable cause) {
super(cause);
}
/* Breaker. */
public void retry();
public boolean shouldRetry();
/* Breaker, ignore events until we've gone up the ancestor
* axis for a specified index. */
public void unwind(int depth);
public boolean shouldUnwind();
public int getUnwindDepth()();
/* Breaker. */
public void pass();
public void shouldPass();
/* For your responder catch ladder. */
public Throwable getCause();
/* Perlish, but whadya gonna do? */
public Map notes();
/* Something I do, so I can create an initialize within
* method parameters. */
public StrategyError note(Object key, Object value);
}
> 3) it knows the details of how to represent itself as a SAX stream or
> a DOM or a String or whatever you might need: in your case that might
> be some form of event wrapper.
This is also new. I'm not thinking it through, but I think this
would be logic in a responder. One could create a generic
responder that does this. The responder gets a reference to the
next SAX handler through the processing context object.
> Then again, I may have missed the whole point of what you're talking
> about. If so, feel free to ignore completely...
> <snip>more complicated details</snip>
Sorry about the details, I hope they don't discourage your
participation in this discussion.
Thank you.
--
Alan Gutierrez - alan@engrm.com
- References:
- Re: [xml-dev] SAXException, checked, buy why?
- From: Alan Gutierrez <alan-xml-dev@engrm.com>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Karl Waclawek <karl@waclawek.net>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Alan Gutierrez <alan-xml-dev@engrm.com>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Karl Waclawek <karl@waclawek.net>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Alan Gutierrez <alan-xml-dev@engrm.com>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Karl Waclawek <karl@waclawek.net>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Alan Gutierrez <alan-xml-dev@engrm.com>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Karl Waclawek <karl@waclawek.net>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Alan Gutierrez <alan-xml-dev@engrm.com>
- Re: [xml-dev] SAXException, checked, buy why?
- From: Peter Hunsberger <peter.hunsberger@gmail.com>
|