Re: Global Exception Handling...

2008-03-11 Thread James Carman
On 3/11/08, Igor Vaynberg [EMAIL PROTECTED] wrote:
The request cycle is easy enough to access anywhere, RequestCycle.get() 
 right?


 im not a big fan of using threadlocals everywhere personally...we
  guarantee certain ones, but they make unit testing, etc, a pita. i
  would prefer passing the instance in.

I'm not a big fan either.  Adding a parameter isn't a bad idea, then.

   If a user needs more advanced search capability, I guess
they could do it themselves.  Maybe the search algorithm could be put
in the RequestCycle class' onRuntimeException() method itself.  Then,
all you'd have to do is override Application.newRequestCycle() and
RequestCycle.onRuntimeException() to plug in your own advanced handler
search capability.  I think this sort of feature is a common enough
need that it could be built in, but that's just my opinion.


 ok. this is making more sense. so we would change Page
  onRuntimeException(RT e) to ExceptionHandler onRuntimeException(RT e),
  and the default resolution algorithm will be what most people agree on
  as the best default. on the other hand, you can just override
  requestcycle.onruntimeexception(rt e) {
   map 
 handlers=beanfactoryutils.beansoftypeincludingancestors(applicationcontext,exceptionhandler.class);
   for (excpetionhandler handler:handlers.values()) {
if (handler.matches(e)) { return e.getPage(e); break; }
   }
   return super.onruntimeexception(e);
  }


The change I was suggesting wouldn't break any existing code (unless
someone implemented IRequestCycleSettings).  The signature of
RequestCycle.onRuntimeException() wouldn't change:

public Page onRuntimeException( Page page, RuntimeException e )
{
IRuntimeExceptionHandler handler = findBestExceptionHandler(e.getClass());
if(handler != null)
{
return handler.onRuntimeException(this, e);
}
return null;
}

protected IRuntimeExceptionHandler findBestExceptionHandler(Class
exceptionClass)
{
while(exceptionClass != null  !exceptionClass.equals(Exception.class))
{
 IRuntimeExceptionHandler handler =
getApplication().getRequestCycleSettings().getRuntimeExceptionHandler(exceptionClass);
if(handler != null)
{
return handler;
}
exceptionClass = exceptionClass.getSuperclass();
}
return null;
}

This way, if the user wants to override the search algorithm, they can
override the findBestExceptionHandler() method.  And, if they haven't
registered any handlers, then this method does exactly what it used to
do (nothing).  Whatever the default algorithm would be of course is up
for debate.  This is just simple example (and off the top of my head,
so if it really doesn't work as is, then sorry).


 our api surface area is already pretty large, makes the framework
  harder to learn. so we try to keep it as small as possible, that is
  not to say we do not implement new ideas/features.


Trust me, I know (about the hard to learn part)!  I signed up to do a
talk on Wicket to our local Java users group (anyone in the
Cincinnati, OH area is free to join us next Monday) and it has now
turned into two talks: Introduction to Wicket and Advanced Wicket (May
2008)!

 i believe most, all that i have worked on, wicket application have
  their own custom subclass of webrequestcycle, so a factory wouldnt
  really benefit anyone if it's only purpose is to make installing a
  generic subclass easier. what you can do is create your own subclass
  of webrequestcycle that has handler registration, that way users can
  subclass yours instead of webrequestcycle and get the handler
  functionality. you can, for example, store registered handlers in
  application metadata facility.

Okay, so it's common to do your own request cycle implementation.  I
didn't realize that.  In Tapestry, RequestCycle wasn't something you
monkeyed around with much.

So, you're saying that I would store my exception handler registry
as metadata entries on the Application class?  I would maybe store my
MapClass,IRuntimeExceptionHandler?  What would the MetaDataKey be?

I just don't want to force users to subclass a custom WebApplication
class.  I'd rather have the IRuntimeRequestHandlers registered with
IRequestCycleSettings (or the IExceptionSettings, maybe?).

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-11 Thread James Carman
On 3/11/08, James Carman [EMAIL PROTECTED] wrote:
 The change I was suggesting wouldn't break any existing code (unless
  someone implemented IRequestCycleSettings).  The signature of
  RequestCycle.onRuntimeException() wouldn't change:


  public Page onRuntimeException( Page page, RuntimeException e )

 {
 IRuntimeExceptionHandler handler = findBestExceptionHandler(e.getClass());
 if(handler != null)
 {
 return handler.onRuntimeException(this, e);
 }
 return null;
  }

  protected IRuntimeExceptionHandler findBestExceptionHandler(Class
  exceptionClass)
  {
 while(exceptionClass != null  !exceptionClass.equals(Exception.class))
 {
  IRuntimeExceptionHandler handler =
  
 getApplication().getRequestCycleSettings().getRuntimeExceptionHandler(exceptionClass);
 if(handler != null)
 {
 return handler;
 }
 exceptionClass = exceptionClass.getSuperclass();
 }
 return null;
  }

  This way, if the user wants to override the search algorithm, they can
  override the findBestExceptionHandler() method.  And, if they haven't
  registered any handlers, then this method does exactly what it used to
  do (nothing).  Whatever the default algorithm would be of course is up
  for debate.  This is just simple example (and off the top of my head,
  so if it really doesn't work as is, then sorry).



By the way, I can create a patch for this stuff if you like.  I guess
the decision needs to be made about where the registry
(MapClass,IRuntimeExceptionHandler) needs to go.  Does it belong in
IRequestCycleSettings or IExceptionSettings?  And, do you want me to
apply it to my already existing code which splits up Settings into
multiple default implementations (which you guys said we should hold
off on for 1.4.x)?

Perhaps there could be logic in there that checks to see if the
requested Page object which caused the RuntimeException implements
IRuntimeExceptionHandler also.  That way, an individual page could
override the global behavior if they wish.  Just a thought.

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-11 Thread Igor Vaynberg
On Tue, Mar 11, 2008 at 3:30 AM, James Carman
[EMAIL PROTECTED] wrote:
  Okay, so it's common to do your own request cycle implementation.  I
  didn't realize that.  In Tapestry, RequestCycle wasn't something you
  monkeyed around with much.

yep, its pretty common.

  So, you're saying that I would store my exception handler registry
  as metadata entries on the Application class?  I would maybe store my
  MapClass,IRuntimeExceptionHandler?  What would the MetaDataKey be?

you would create your own, preferrably inner private, subclass of
MetaDataKey and use that. that way no body but you can access those
entries.

  I just don't want to force users to subclass a custom WebApplication
  class.

thus my suggestion of using metadata

 I'd rather have the IRuntimeRequestHandlers registered with
  IRequestCycleSettings (or the IExceptionSettings, maybe?).

well, another thing here is that there are two ways of setting this
up. one way is to push handlers into the request cycle, another way is
to have request cycle lookup the handlers from some registry. if i
were using spring, as i assume you are, i would create a registry bean
for the handlers that would live in spring context and collect all the
beans. the request cycle would then simply lookup this registry bean
and iterate over registered handlers.

this is kinda why we try not to put things like this into core.
implementations vary a lot based on how your architecture is setup and
forcing one particular way makes code for others inelegant...

-igor

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-11 Thread Igor Vaynberg
On Tue, Mar 11, 2008 at 3:51 AM, James Carman
[EMAIL PROTECTED] wrote:
  By the way, I can create a patch for this stuff if you like.  I guess
  the decision needs to be made about where the registry
  (MapClass,IRuntimeExceptionHandler) needs to go.  Does it belong in
  IRequestCycleSettings or IExceptionSettings?

i think you should hold off on the patch until you have settled down
on how you want to do this

 And, do you want me to
  apply it to my already existing code which splits up Settings into
  multiple default implementations (which you guys said we should hold
  off on for 1.4.x)?

we havent decided if we are going to apply that patch or not, just
that we cant even start thinking about it until 1.4. i would say its
safer to create a patch off standard trunk.

  Perhaps there could be logic in there that checks to see if the
  requested Page object which caused the RuntimeException implements
  IRuntimeExceptionHandler also.  That way, an individual page could
  override the global behavior if they wish.  Just a thought.

that might make sense. but you have to realize that Page is a pretty
coarse scope for something like this. a lot of applications consist of
few pages that only act as containers for panels that are swapped in
and out, so i can have an application that is made up of one page and
everything else is madeup of panels that i swap in and out in that
main container page...

-igor

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Global Exception Handling...

2008-03-10 Thread James Carman
If I'm developing a Hibernate-based application and I want to install
some global StateObjectStateException handling code, what's the best
way to do it?  I could override Application.newRequestCycle()
providing my own request cycle implementation which overrides the
onRuntimeException() method.  Is there a way to plug in logic which
says if you see exception type X, use this handler?

James

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-10 Thread Igor Vaynberg
On Mon, Mar 10, 2008 at 7:39 PM, James Carman
[EMAIL PROTECTED] wrote:
 If I'm developing a Hibernate-based application and I want to install
  some global StateObjectStateException handling code, what's the best
  way to do it?  I could override Application.newRequestCycle()
  providing my own request cycle implementation which overrides the
  onRuntimeException() method.  Is there a way to plug in logic which
  says if you see exception type X, use this handler?

notice requestcycle.onruntimeexception() has access to the exception,
and returns a page, so

myrc.onruntimexception(runtimeexception e) {
  if (e.getrootcause() instanceof hibernateexception) {
  return new hibernateerrorpage(e);
  }
}

-igor



  James

  -
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-10 Thread James Carman
On 3/10/08, Igor Vaynberg [EMAIL PROTECTED] wrote:
 On Mon, Mar 10, 2008 at 7:39 PM, James Carman
  [EMAIL PROTECTED] wrote:
   If I'm developing a Hibernate-based application and I want to install
some global StateObjectStateException handling code, what's the best
way to do it?  I could override Application.newRequestCycle()
providing my own request cycle implementation which overrides the
onRuntimeException() method.  Is there a way to plug in logic which
says if you see exception type X, use this handler?


 notice requestcycle.onruntimeexception() has access to the exception,
  and returns a page, so

  myrc.onruntimexception(runtimeexception e) {
   if (e.getrootcause() instanceof hibernateexception) {
   return new hibernateerrorpage(e);
   }
  }

Okay, so this is the way to handle it, eh?  I just wanted to make sure
there was nothing out there already for this.  I may make up a
Spring-based solution that allows me to register an exception
handler for specific types of runtime exceptions.  That way, my forms
don't need to know I'm using Hibernate.  They can just deal with my
domain interface (a repository).  Thanks for the tip!

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-10 Thread James Carman
On 3/10/08, James Carman [EMAIL PROTECTED] wrote:
 On 3/10/08, Igor Vaynberg [EMAIL PROTECTED] wrote:
   On Mon, Mar 10, 2008 at 7:39 PM, James Carman
[EMAIL PROTECTED] wrote:
 If I'm developing a Hibernate-based application and I want to install
  some global StateObjectStateException handling code, what's the best
  way to do it?  I could override Application.newRequestCycle()
  providing my own request cycle implementation which overrides the
  onRuntimeException() method.  Is there a way to plug in logic which
  says if you see exception type X, use this handler?
  
  
   notice requestcycle.onruntimeexception() has access to the exception,
and returns a page, so
  
myrc.onruntimexception(runtimeexception e) {
 if (e.getrootcause() instanceof hibernateexception) {
 return new hibernateerrorpage(e);
 }
}


 Okay, so this is the way to handle it, eh?  I just wanted to make sure
  there was nothing out there already for this.  I may make up a
  Spring-based solution that allows me to register an exception
  handler for specific types of runtime exceptions.  That way, my forms
  don't need to know I'm using Hibernate.  They can just deal with my
  domain interface (a repository).  Thanks for the tip!


What if we changed IRequestCycleSettings to include these methods:

public void addRuntimeExceptionHandler(Class exceptionClass,
IRuntimeExceptionHandler handler);
public IRuntimeExceptionHandler getRuntimeExceptionHandler(RuntimeException e);


Then, add the IRuntimeExceptionHandler interface:

public interface IRuntimeExceptionHandler
{
  public Page onRuntimeException(Page page, RuntimeException e);
}

Then, RequestCycle's onRuntimeException() method as follows:

public void onRuntimeException(Page page, RuntimeException e)
{
  IRuntimeExceptionHandler handler =
Application.get().getRequestCycleSettings().getRuntimeExceptionHandler(e);
  if( handler != null )
  {
return handler.onRuntimeException(page,e);
  }
  return null;
}

This way, folks could install their own exception handlers very
easily.  The getRuntimeExceptionHandler() method would do a search up
the class hierarchy if necessary, so you could install a handler for
IOException which would cover FIleNotFoundException, for instance.
What do you think?

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-10 Thread Igor Vaynberg
you might also need access to the request cycle inside the
exceptionhandler, so thats three arguments now...maybe on exception
you want to set a 503 error

also what is the search order for handler resolution? do we go root
cause-outer or outer-root cause? both can make sense in certain
situations which would make handler resolution ambiguous...

we prefer to keep wicket bare and let users come up with their own
solutions for these sorts of thing, that work exactly how they want.

-igor


On Mon, Mar 10, 2008 at 9:20 PM, James Carman
[EMAIL PROTECTED] wrote:
 On 3/10/08, James Carman [EMAIL PROTECTED] wrote:
   On 3/10/08, Igor Vaynberg [EMAIL PROTECTED] wrote:
 On Mon, Mar 10, 2008 at 7:39 PM, James Carman
  [EMAIL PROTECTED] wrote:
   If I'm developing a Hibernate-based application and I want to install
some global StateObjectStateException handling code, what's the best
way to do it?  I could override Application.newRequestCycle()
providing my own request cycle implementation which overrides the
onRuntimeException() method.  Is there a way to plug in logic which
says if you see exception type X, use this handler?


 notice requestcycle.onruntimeexception() has access to the exception,
  and returns a page, so

  myrc.onruntimexception(runtimeexception e) {
   if (e.getrootcause() instanceof hibernateexception) {
   return new hibernateerrorpage(e);
   }
  }
  
  
   Okay, so this is the way to handle it, eh?  I just wanted to make sure
there was nothing out there already for this.  I may make up a
Spring-based solution that allows me to register an exception
handler for specific types of runtime exceptions.  That way, my forms
don't need to know I'm using Hibernate.  They can just deal with my
domain interface (a repository).  Thanks for the tip!
  

  What if we changed IRequestCycleSettings to include these methods:

  public void addRuntimeExceptionHandler(Class exceptionClass,
  IRuntimeExceptionHandler handler);
  public IRuntimeExceptionHandler getRuntimeExceptionHandler(RuntimeException 
 e);


  Then, add the IRuntimeExceptionHandler interface:

  public interface IRuntimeExceptionHandler
  {
   public Page onRuntimeException(Page page, RuntimeException e);
  }

  Then, RequestCycle's onRuntimeException() method as follows:

  public void onRuntimeException(Page page, RuntimeException e)
  {
   IRuntimeExceptionHandler handler =
  Application.get().getRequestCycleSettings().getRuntimeExceptionHandler(e);
   if( handler != null )
   {
 return handler.onRuntimeException(page,e);
   }
   return null;
  }

  This way, folks could install their own exception handlers very
  easily.  The getRuntimeExceptionHandler() method would do a search up
  the class hierarchy if necessary, so you could install a handler for
  IOException which would cover FIleNotFoundException, for instance.
  What do you think?



  -
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-10 Thread James Carman
On 3/11/08, Igor Vaynberg [EMAIL PROTECTED] wrote:
 you might also need access to the request cycle inside the
  exceptionhandler, so thats three arguments now...maybe on exception
  you want to set a 503 error

  also what is the search order for handler resolution? do we go root
  cause-outer or outer-root cause? both can make sense in certain
  situations which would make handler resolution ambiguous...

  we prefer to keep wicket bare and let users come up with their own
  solutions for these sorts of thing, that work exactly how they want.


The request cycle is easy enough to access anywhere, RequestCycle.get() right?

I hadn't thought of the root cause stuff, admittedly.  However, just
going up the main hierarchy is probably sufficient for a majority of
use cases.  If a user needs more advanced search capability, I guess
they could do it themselves.  Maybe the search algorithm could be put
in the RequestCycle class' onRuntimeException() method itself.  Then,
all you'd have to do is override Application.newRequestCycle() and
RequestCycle.onRuntimeException() to plug in your own advanced handler
search capability.  I think this sort of feature is a common enough
need that it could be built in, but that's just my opinion.

I'm somewhat new to the Wicket community, so maybe I just didn't get
the Wicket philosophy.  That doesn't mean that I won't offer
suggestions that I find useful anymore. :)  Keeping the core framework
bare is a good approach.

Another thought I had is that inside the new methods on Application,
maybe it could call a factory instead of doing the logic itself.
Then, the factory could be configured by subclasses to override the
default behavior rather than having to implement the method
themselves.  For instance, you could come up with a
IRequestCycleFactory interface.  So, if I were to write a little
project that does what I want w.r.t. this exception handler stuff, all
someone would have to do in their application is plug in my
IRequestCycleFactory implementation to get that functionality.  They
wouldn't have to extend my Application superclass (what if they wanted
to use another library which requires the extension of an Application
superclass also?).  The same sort of stuff could be done for Sessions,
etc.

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Global Exception Handling...

2008-03-10 Thread Igor Vaynberg
On Mon, Mar 10, 2008 at 9:55 PM, James Carman
[EMAIL PROTECTED] wrote:
 On 3/11/08, Igor Vaynberg [EMAIL PROTECTED] wrote:
   you might also need access to the request cycle inside the
exceptionhandler, so thats three arguments now...maybe on exception
you want to set a 503 error
  
also what is the search order for handler resolution? do we go root
cause-outer or outer-root cause? both can make sense in certain
situations which would make handler resolution ambiguous...
  
we prefer to keep wicket bare and let users come up with their own
solutions for these sorts of thing, that work exactly how they want.
  

  The request cycle is easy enough to access anywhere, RequestCycle.get() 
 right?

im not a big fan of using threadlocals everywhere personally...we
guarantee certain ones, but they make unit testing, etc, a pita. i
would prefer passing the instance in.

  I hadn't thought of the root cause stuff, admittedly.

we, as core devs, try to think of all angles before adding something
like this into core :)

 However, just
  going up the main hierarchy is probably sufficient for a majority of
  use cases.

thats one data point. we would have to open this up to the community
before we make a decision though.

 If a user needs more advanced search capability, I guess
  they could do it themselves.  Maybe the search algorithm could be put
  in the RequestCycle class' onRuntimeException() method itself.  Then,
  all you'd have to do is override Application.newRequestCycle() and
  RequestCycle.onRuntimeException() to plug in your own advanced handler
  search capability.  I think this sort of feature is a common enough
  need that it could be built in, but that's just my opinion.

ok. this is making more sense. so we would change Page
onRuntimeException(RT e) to ExceptionHandler onRuntimeException(RT e),
and the default resolution algorithm will be what most people agree on
as the best default. on the other hand, you can just override
requestcycle.onruntimeexception(rt e) {
  map 
handlers=beanfactoryutils.beansoftypeincludingancestors(applicationcontext,exceptionhandler.class);
  for (excpetionhandler handler:handlers.values()) {
   if (handler.matches(e)) { return e.getPage(e); break; }
  }
  return super.onruntimeexception(e);
}

that is about 5 lines of code and it doesnt force a specific algorithm
or exception handler onto the user...

  I'm somewhat new to the Wicket community, so maybe I just didn't get
  the Wicket philosophy.  That doesn't mean that I won't offer
  suggestions that I find useful anymore. :)

definately please do. we appreciate all the feedback. please dont take
me pushing back as a way to discourage you.

 Keeping the core framework
  bare is a good approach.

our api surface area is already pretty large, makes the framework
harder to learn. so we try to keep it as small as possible, that is
not to say we do not implement new ideas/features.

  Another thought I had is that inside the new methods on Application,
  maybe it could call a factory instead of doing the logic itself.
  Then, the factory could be configured by subclasses to override the
  default behavior rather than having to implement the method
  themselves.  For instance, you could come up with a
  IRequestCycleFactory interface.  So, if I were to write a little
  project that does what I want w.r.t. this exception handler stuff, all
  someone would have to do in their application is plug in my
  IRequestCycleFactory implementation to get that functionality.  They
  wouldn't have to extend my Application superclass (what if they wanted
  to use another library which requires the extension of an Application
  superclass also?).  The same sort of stuff could be done for Sessions,
  etc.

i believe most, all that i have worked on, wicket application have
their own custom subclass of webrequestcycle, so a factory wouldnt
really benefit anyone if it's only purpose is to make installing a
generic subclass easier. what you can do is create your own subclass
of webrequestcycle that has handler registration, that way users can
subclass yours instead of webrequestcycle and get the handler
functionality. you can, for example, store registered handlers in
application metadata facility.

-igor

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]