Re: Global Exception Handling...
On 3/11/08, Igor Vaynberg <[EMAIL PROTECTED]> wrote: > 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" > > (Map > IRequestCycleSettings or IExceptionSettings? > > > i think you should hold off on the patch until you have settled down > on how you want to do this Well, that's what I'm trying to figure out. How do you guys think this should be done? 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)? > > > 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. > Well, that patch lets us Spring folks configure our applications much easier via Spring. The Application's settings objects are settable, so you could configure a DefaultRequestCycleSettings bean in Spring and add in your global handlers there (then set it on your Application bean). It also shouldn't break any existing code, because the API doesn't change. > > > 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... > It was just a suggestion. Perhaps we could start with the global level and then allow customizing at some finer granularity later (if needed). - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Global Exception Handling...
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" > (Map 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]
Re: Global Exception Handling...
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 > Map? 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...
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" (Map
Re: Global Exception Handling...
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 Map? 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...
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]
Re: Global Exception Handling...
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...
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...
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...
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...
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]