Hello Leo!

LS> I'm jumping in on the discussion a bit late, so you may already 
LS> have covered this ground

No you're not! It's who is turning the discussion into this side.
It's me who comes up with the idea of cutting the stack trace
based on the exception type. So all comments welcome! :-)

LS>  - but I must admit to not really
LS> seeing the purpose of minimizing stack traces by not printing
LS> stack traces for certain exceptions.

Well, I think some exceptions are expected.
ConfigurationException is expected when users supply
invalid configuration.

Moreover, if we make sure this exception alone carries enough
info to trace the problem, e.g. it has

*   Configuration.getLocation() including full path name and line
    number
*   the id and probably type of the offending component

    (that's what I'm thinking about - probably subclassing
    ConfigurationException and adding the info there, or
    putting it somehow into message, or changing the
    ConfigurationException itself, or changing
    CascadingException - you see I'm not afraid to touch
    the most sacred things :-)

Anyway, if ConfigurationException has both location and
coponent information then we do not need a stack trace.

(Or need it when the level of logging is debug)

Moreover, a component id is somewhat better then
a stack trace. Stack trace gives only the class the caused
the exception and if we have several components of the same
class but with different ids, the id is better.

So, ConfigurationException is expected (as users mistype
the configuration for instance) and it is nice to print
only component id + location for it.

Now, if one component failed to startup we can either
* stop immediately (it would be okay to me)
* or do what currently fortress/impl/AbstractContainer.initialize()
  does - try to bring up all we can, collect all the exceptions
  and fail after that (I do not mind that also)

Well, I sort of do not want to change much if I can change little.
If AbstractContainer collects exceptions into a CompositeException
I do not mind.

But then I would like to nicely handle these exceptions also.
In fact if component A failed because it could not get component B
we also do not need a stack trace for this (unless we're at
DEBUG log level). So I was trying to break a path for it too.

To me the path looks somewhat like this: such a failure
most likely will be expressed as a ServiceException.

Very good. Now we should make sure that the ServiceException
has info conveyed on the id of the component _on behalf of which
the operation was attempted_ (again like with ConfigurationException
there are a plethora of options where we can put this info) and
we're fine: we do not need a stack trace again.

Same with ContextException, looks like we avoid the stack trace.
(But ContextException probably got into the list by mistake,
the original intention was to catch a ConfigurationException,
handle it nicely w/o a stack trace and handle the subsequent
ServiceExceptions equally nicely. Leif has made a valid point
that users get very frightened by stack traces and call him
for support as soon as they see one and I have found that
I'm doing exactly the same in my user code - I omit stack
traces for Cofiguration exceptions and I am very pleased
with the result so far.

Peter Royal has yet another approach: he has suggested
to have two logs: one user log without exceptions and
one developer's log with exceptions. Very nice indeed.
But I got to like so much to get little quite error
messages w/o stack traces in the developer's log too,
that I found it reasonable to continue discussion on
the topic. This is something I'm doing for myself
anyway. Probably this has value. Discussion will show! :-)
    
LS> The general consensus appears to be that if any component
LS> fails, the whole container & all components in it are essentially
LS> completely broken.
That would be fine by me, but currently Fortress runs differently.
And there some caveats: for instance with lazy or background
initialization how can you shut down the system if a component
initialization fails? So this probably works only with inline
initialization. Activation policy inline has (unintentionally?)
become the 'required component' policy as well.

LS> Thus, these exceptions should happen very rarely.
In fact I only want some certain cases (like broke config)
to be logger w/o stack traces. Of course all the unforseen
circumstances (including these rare catastrophes should be
logger completely, and if we're talking about this, it's
probably okay to make users call support in this case!).

LS> But when they do happen, having a full stack trace is very
LS> helpful. In fact, a constant annoyance for me is that
LS> an exception thrown in a SAX ContentHandler gets wrapped
LS> in a SAXException and appears like one, requiring manual
LS> unwrapping in order to figure out just what really happened!

Errr... terrible...

To me 2 things are BAD about SAX exception:

* the toString() method is just an assassination of a sane
  mind to be invoked - calling toString() of the nested
  exception - it is more then terrible IMO!
  
* a nesting mechanism different from getCause()
  yes, I guess SAXException was invented before JDK 1.4 :-)
  but now its a problem

The solution IMO is

a) never call toString() on SAXException (and hence on
   any exception probably), but to use

   t.getClass().getName() + ": " + t.getMessage()

   (getMessage() does not seem to be broken on SAXException
   if I'm not mistaken)

   if I'm not mistaken our current loggers all behave like this

b) to unwind nested exceptions not only look at getCause()
   but also check to see if we're dealing with a SAXException
   and in the latter case handle getException() identically
   to getCause(). Our logger do not do that ATM, AFAIK.

   Probably will teach them one day to do that.
   Or you will :-)

   I guess we could easily put that into Avalon formatter.

   Probably even in other formatters in log kit?

   Do you know by any chance what does Log4J do about it?
  
And don't get me wrong: when I speak about cutting stack
traces I _by no means do not want to_ cut nested exception
unwinding as well.

To be true I was thinking about adding the following formatter
to LogKit

<formatter>
  <format> ... %{message}.. </format>
  <no-stack>
     ConfigurationException
     ServiceException-
  </no-stack>
</formatter>

you see those minus? ('-')?
I wanted it to denote that the nested exceptions shouldn't
be unwinded for that exactly exception. But I wanted that
to be optional.

Instead I wanted the unwinding to happen, but the stacks
to be cut _at the inner levels too_ by the same rule for
all levels. So we could have

ActivationFailedException: id='k'
  caused by: ConfigurationException: id='k': foo bar:file:/D:/conf/a.xconf:22
    caused by: ... (why not?)
  

LS> So policy should be this:

LS>   1. Always err
?? what is it ?? :-)

LS> on the side of printing when printing
LS>      stack traces.
LS> Print too much rather than too little.
Well my preference would be for this to happen only
when log level is DEBUG.
I keep more to Leif's opinion that it the stack traces should
be cut for ConfigurationException rather then with Peter Royal's
that we should have two logs (may change my mind in the future :-)

LS>   2. It is better to just *stop* the initialization process
LS>      at the first exception.
It would be okay by me, but
a) it is not now that way
b) lazy and background initialization policies spoil this nice
   intention to fail fast, don't they?


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

Reply via email to