Do you have the title to Ceki's book?

-----Original Message-----
From: news [mailto:[EMAIL PROTECTED] On Behalf Of Leo Simons
Sent: Thursday, August 28, 2003 6:27 PM
To: [EMAIL PROTECTED]
Subject: Logging, IoC and Avalon (was: Re: Useful error messages)

Stephen McConnell wrote:
> Finally, onto some Avalon concerns.
> 
> Two points:
> 
> (a) configuration exceptions would be more useful if they contained
> the offending fragment

indeed. Howard's HiveMind solves this beautifully: it reports the 
filename and line number for any config error. I expect its trivial in 
hivemind to expand on that information to get some surrounding context.

> (b) better specs are needed about component/container seperation
> of responsibilities (e.g. who handled error reporting)

specs? Why specs? How about some general guidelines?

"Log then rethrow at any containment boundary"

A server logs details of an internal exception, then sends on less 
detailed information to the client. A servlet applications logs details 
of an internal exception, then sends on less detailed information to the 
servlet container.

That's the general rule. However, it makes sense to offload log 
management towards the container in an IoC application. If/when you do 
that, you should trust the container to do logging properly for you.

More concretely, anytime you throw an exception from any lifecycle 
method that is an subclass of CascadingException and/or 
CascadingThrowable, and you provide the "cause" of the exception, do not 
log that cause seperately, it will be done for you. If you do not
provide the "cause" when rethrowing, *do* log the cause but not the rest:

        catch( SomeException se )
        {
                getLog().error( "whoops", se );
                throw new ServiceException( "some.thing" );
        }
or
        catch( SomeException se )
        {
                throw new ServiceException( "some.thing", se );
        }
not
        // will print a stacktrace twice with any worthwile
        // logger
        catch( SomeException se )
        {
                getLog().error( "whoops", se );
                throw new ServiceException( "some.thing", se );
        }
nor
        // will print a stacktrace trice with any worthwile
        // logger
        catch( SomeException se )
        {
                getLog().error( "whoops", se );
                se.printStackTrace();
                throw new ServiceException( "some.thing", se );
        }

with non-lifecycle methods, things are a bit different. You *may* be 
crossing an application boundary; depends on your component granularity. 
If you have

interface RequestHandler
{
        Response handle( Request request )
                throws RequestException;
}

I will bet you that you will often not want to return the cause of the 
RequestException. So here you always have

        catch( SomeException se )
        {
                // record specifics with this component
                getLog().error( "whoops", se );

                // rethrow a more generic exception; don't give
                // clients information about the internals of the
                // implementation
                throw new RequestException( 500 );
        }

All this is hardly avalon-specific. There's several books that deal with 
the generic issue. I believe Ceki wrote a nice one (that I haven't read 
though).

all IMHO.

cheers!

- LSD



---------------------------------------------------------------------
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]

Reply via email to