I agree with the idea. But what about the InvocationTargetException?

Having a wrapping exception for Exceptions that are thrown from invoked
user methods helps finding out where the problem is - that way the user
is sure that it is his fault and not something in the library.

BTW, I would suggest using a method declared as:
  java.lang.Throwable getRootCause()

to get the original exception from InvocationTargetException. This way
one follows the ServletException "convention" with the additional
advantage that Tomcat (at least 3.3, but I believe it is common code)
will print the Original Exception and its call stack. (Besides,
"getRootCause()" sounds more explicit to me than "getTargetException()",
but that might just be personal preference.)


This happens because Tomcat tries to get an original exception calling
a few possible methods "by name". Follows the source for the Tomcat
method that does the trick, since it is an interesting piece of code.
It comes from package org.apache.tomcat.util.log, class Logger:


    private static void printThrowable(PrintWriter w, Throwable t, String
rootcause, int depth ) {

        if (t != null) {
            // XXX XXX XXX Something seems wrong - DOS, permissions. Need to
            // check.
            t.printStackTrace(w);

            // Find chained exception using few general patterns

            Class tC=t.getClass();
            Method mA[]= tC.getMethods();
            Method nextThrowableMethod=null;
            for( int i=0; i< mA.length ; i++  ) {
                if( "getRootCause".equals( mA[i].getName() )
                    || "getNextException".equals( mA[i].getName() )
                    || "getException".equals( mA[i].getName() )) {
                    // check param types
                    Class params[]=mA[i].getParameterTypes();
                    if( params==null || params.length==0 ) {
                        nextThrowableMethod=mA[i];
                        break;
                    }
                }
            }

            if( nextThrowableMethod != null ) {
                try {
                    Throwable nextT=(Throwable)nextThrowableMethod.invoke( t ,
emptyObjectArray );
                    if( nextT != null ) {
                        w.println(rootcause);
                        if( depth > 0 ) {
                            printThrowable(w, nextT, rootcause, depth-1);
                        }
                    }
                } catch( Exception ex ) {
                    // ignore
                }
            }
        }
    }


Have fun,
Paulo Gaspar


> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On
> Behalf Of Geir Magnusson Jr.
>
> Sean Legassick wrote:
> >
> > On Tue, Feb 27, 2001 at 08:00:31AM -0500, Geir Magnusson Jr. wrote:
> >
> > > Just to summarize so it's clear - you are not looking for invocation
> > > exceptions to be thrown (because those are a natural part of the
> > > introspection flail-o-matic in some places, but any exceptions *your*
> > > methods throw to propogate, right?
> >
> > Yep, absolutely (although given enough prodding of an invocation
> > exception one can get at the heart of the problem anyway, but it
> > probably makes sense to strip that layer away - like you say its just
> > part of the introspection mechanism gubbins)...
>
> I was thinking about this and looking through the code.
>
> I think its a good idea to propagate exceptions from method invocations
> out through Template.merge().
>
> I can enumerate why if anyone needs details - the short answer is that I
> think that you need to know during runtime, in the Controller layer,
> when something goes wrong.  That way you can do something intelligent,
> like switch templates, email the admin, panic, whatever :)
>
> This will turn out to be very important in the 'Pull Model' - there is
> no other way that an application can gracefully recover from an error -
> the template shouldn't have to deal with it.  (Users calling saying the
> site is hosed doesn't cut it either... :)
>
> It will take a little care and work (so I am not doing it tonight - too
> fogged in - and wanted to solicit opinions...)
>
> To summarize :
>
>  public void merge( Context context, Writer writer)
>         throws ResourceNotFoundException, ParseErrorException, Exception
>
> where Exception can also be exceptions thrown from in-context method
> invocations.
>
> We can make a new exception (one of the o.a.v.e set), but I don't really
> see any point.
>
> The public API won't change at all, so no code should notice (other than
> they have a chance to deal with problems.
>
> geir
>
> --
> Geir Magnusson Jr.                               [EMAIL PROTECTED]
> Developing for the web?  See http://jakarta.apache.org/velocity/
>

Reply via email to