incubator-kato-spec mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Julin <...@us.ibm.com>
Subject Re: Kato API javadoc - error handling
Date Wed, 15 Apr 2009 00:17:38 GMT

It seems to me that with all this discussion of polymorphic and stackable
error handlers, we're rapidly re-inventing much of the Java exception
facility, and probably rediscovering a lot of the same design
considerations that the original designers of that Java exception facility
faced...

As far as I can tell, the one major difference is that, with Java
exceptions, once an exception is thrown, the flow of control is irrevocably
interrupted and can only resume after the exception handler, not back at
the point where the exception was thrown. This means that if you do want
fine control over your errors but don't want to interrupt a whole sequence
of operations, you're forced to put an explicit try/catch block at every
line of the program. Whereas with these proposed handlers, a single
top-level handler could presumably take care of all the errors in a
sequence of operations without interrupting that sequence.

Is that a correct interpretation? And is there no practical way to achieve
the same effect with actual Java exceptions? Some sort of "continue"
statement inside a catch block, maybe?


On the other hand, one thing that Java try/catch blocks offer is controlled
access to the local variables of the method in which the try/catch block
resides, and to the private instance members of the object. The proposed
handlers, since they are executing in a separate object and a separate
method, would not enjoy a similar access. Whether this limitation would
prove bothersome in practice, will depend on the actual usage scenarios
that we face...


-- Daniel --



Nicholas.Sterling@Sun.COM wrote on 2009-04-14 05:39:40 PM:
> If we were to end up doing something like this, would we use checked or
> unchecked exceptions?  If we use checked exceptions, the client will
> still have to catch the exception or say that the method throws it.
> Presumably that would defeat the purpose...
>
> Good idea on the comparison code.  I'm a little concerned that people
> may think we are overengineering the whole exception thing; once we have
> the comparison code, we can run it by some folks and see whether their
> brains short-circuit.
>
> It might be helpful as a reference point to consider an example with
> another API.  I was sufficiently frustrated by the unreadability of my
> JDBC clients that I wrote a pair of classes, Query and Querier, that
> hide gory details, and I think it makes a big difference.  Among the
> hidden are the binding of variables and iterating through result sets,
> but probably the biggest benefit is from hiding the exception-handling
> logic (it closes the ResultSet for you on an exception). This is what it
> looks like to use it:
>
>     // Create a query to get recent bugs.
>     static final Query recent_bugs_query = new Query(
>         "bugs submitted against a PRODUCT in the last NUM DAYS",
>         "select id, synopsis from bugs " +
>        " where product = ? and date_submitted > sysdate - ?"
>     );
>     ...
>     // Given a Connection conn and values for PRODUCT and NUM DAYS,
>     // query the DB for recent bugs and display the resulting rows.
>     new Querier( recent_bugs_query, conn, product, num_days ) {
>         public void doRow() throws SQLException {
>             System.out.println( rs.getString(1) + " " + rs.getString
(2) );
>         }
>     }
>
> A major benefit was getting rid of that awful doubly-nested catch block
> (closing the ResultSet in the catch block may throw an exception, so it
> requires its own try-catch -- gaah!).
>
> The default Querier throws an exception, but you can extend Querier and
> override the handleException() method to do whatever is appropriate for
> your app, and they use your custom Querier throughout your program, e.g.
>
>     class MyQuerier extends Querier {
>         void handleException( Exception ex ) {
>             ....
>         }
>     }
>
> Perhaps we could use a similar approach, for example providing a
> HeapQuerier class from which clients create anonymous classes to do what
> they want.
>
> Nicholas
>
>
>
> Steve Poole wrote:
> > On Mon, Apr 13, 2009 at 4:34 AM, Nicholas Sterling <
> > Nicholas.Sterling@sun.com> wrote:
> >
> >
> >> And a Handler (whatever it should really be called) would have access
to
> >> the previous Handler on the stack, so it could do
> >>
> >>   void handleJavaObjectUnavailable(...) {
> >>       // do some stuff, then defer to the guy beneath us on the stack:
> >>       prevHandler().handleJavaObjectUnavailable(...);
> >>   }
> >> Nicholas
> >>
> >> This is cool -  The callback approach is sort of a half way
housebetween a
> >>
> > DOM and SAX model.  It could allow us to have a default "no nulls"
approch
> > for an implementation but still allows for users of the API to do
something
> > different.
> >
> > I think we should create some comparison code segments to see what it
could
> > look like.
> >
> >
> >> Nicholas Sterling wrote:
> >>
> >>
> >>> Daniel Julin wrote:
> >>>
> >>>
> >>>> I like that approach a lot, because it may also address the other
concern
> >>>> that a proposed "default reasonable behavior" may not be appropriate
for
> >>>> all usage scenarios. We could probably come-up with a variety of
handlers
> >>>> for various common behaviors, like printing a simple error message,
> >>>> completely ignoring the error, and lots of other creative responses.
> >>>>
> >>>> Incidentally, nothing in this discussion is particularly specific to
the
> >>>> Kato API, is it? Are we saying that, in general, we don't like
exceptions
> >>>> as the standard mechanism to report errors in Java, and that we're
> >>>> inventing new patterns?  If so, have any useful patterns been
proposed
> >>>> and
> >>>> documented previously in the literature?
> >>>>
> >>>>
> >>>>
> >>> I just looked around a little, and am only seeing suggestions for how
the
> >>> *client* can abstract out the exception-handling logic using the
Template
> >>> design pattern.  So far I haven't seen any advice for API designers.
> >>>
> >>> By the way, it occurred to me that the setter can have a generic name
> >>> because overloading will allow us to have a method for each
condition:
> >>>
> >>>   factory.setHandler( new DataUnavailableHandler( ... ) {
> >>>       ...
> >>>   } );
> >>>
> >>> Also, it might make sense to push the handler on a stack rather
replace
> >>> what is there.  That will allow independent modules to modify just
that
> >>> behavior they need to and then remove those modifications when they
are no
> >>> longer needed.  It also means that we can have just one Handler
> () class for
> >>> all the handlers, e.g.
> >>>
> >>>   // Temporarily override the handling of DataUnavailable errors.
> >>>   factory.pushHandler( new Handler( ... ) {
> >>>       void handleJavaObjectUnavailable(...) {
> >>>           // handling specific for JavaObjects
> >>>       }
> >>>       void handleDataUnavailable(...) {
> >>>           // handling for all other DataUnavailable conditions
> >>>       }
> >>>       // All handler methods not overridden will simply call the same
> >>> method
> >>>       // for the object beneath us on the stack.  If we get to the
bottom,
> >>> the
> >>>       // handler there will throw an exception.
> >>>   } );
> >>>   // Do some work that might cause an exception.  This might include
> >>> calling
> >>>   // an independently written module that also wants to temporarily
> >>> override
> >>>   // some handler, but they will pop that before returning to us.
> >>>   factory.popHandler();
> >>>
> >>> Nicholas
> >>>
> >>>
> >>>
> >>>> -- Daniel --,
> >>>>
> >>>>
> >>>> Nicholas.Sterling@Sun.COM wrote on 2009-04-11 01:48:53 AM:
> >>>>
> >>>>
> >>>>
> >>>>> Daniel Julin wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>>> I guess a two mode approach would make everyone happy. But would
it
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>> make
> >>>>>
> >>>>
> >>>>> the API too complicated?
> >>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>> I have some sympathy for what Steve is talking about -- maybe my
> >>>>> short-term memory is small, but when lots of single lines of code
> >>>>> inflate to 6 lines (and two indentation levels), it is definitely
harder
> >>>>> for me to read.  However, I wouldn't want to give up the certain
and
> >>>>> immediate catching of errors offered by exceptions.
> >>>>>
> >>>>> Would a mechanism like this work for the two-mode approach?
> >>>>>
> >>>>>    factory.setDataUnavailableHandler( new DataUnavailableHandler
( ... )
> >>>>>
> >>>>>
> >>>>>
> >>>> {
> >>>>
> >>>>
> >>>>
> >>>>>        ...
> >>>>>    } );
> >>>>>
> >>>>> All objects created by the factory would call that object's
> >>>>> dataUnavailable() method when appropriate, passing it enough info
about
> >>>>> what was going on to allow the method to make interesting decisions
> >>>>> about what to do.  The default handler would always throw a
> >>>>> DataUnavailableException.
> >>>>>
> >>>>> It's hard for me to tell whether something like that would really
> >>>>> suffice in actual use.  Perhaps it would have to be finer-grained,
with
> >>>>> methods for javaObjectUnavailable(), imageSectionUnavailable(),
etc.
> >>>>> Perhaps the defaults for those would call the more generic
> >>>>> dataUnavailable() so that you could intervene for all cases and/or
for
> >>>>> individual cases as desired.
> >>>>>
> >>>>> Nicholas
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>
> >>>>
> >>>
> >
> >
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message