While attempting to trace a bug in one of the tasks, I came across a
'feature' of .NET exception handling: rethrowing a caught exception
overwrites the stack trace of the original exception.
Specifically, in the Execute method for the Task class, exceptions thrown in
the ExecuteTask template method are caught and rethrown depending on whether
or not FailOnError is set.  The problem with this is that the stack trace is
overwritten on the rethrown exception making it very difficult to trace
exactly where the failure occurred within the task.
There are two ways to address this issue.  One is to try to make the catch
clause only catch specific exceptions.  This means that unhandled exceptions
will filter through and be logged to the console with their full stack
trace.  The other is to wrap the captured exception in a newly thrown
exception.  This will keep the original stack trace intact.  The stack trace
for the inner exception will be displayed by invoking the ToString() method
on the wrapping exception.
I would suggest applying both approaches.  Here is my version of the Execute
method:

        /// <summary>Executes the task unless it is skipped.</summary>
        public void Execute() {
            if (IfDefined && !UnlessDefined) {
                try {
                    Project.OnTaskStarted(this, new BuildEventArgs(Name));
                    ExecuteTask();
                } catch (BuildException e) {
                    if (FailOnError) {
                        throw new BuildException("Exception occurred in
executing task", e);
                    } else {
                        Log.WriteLine(e.ToString());
                    }
                } finally {
                    Project.OnTaskFinished(this, new BuildEventArgs(Name));
                }
            }
        }

Line 76 of the IncludeTaskTest will need to be changed in order to get a
successful build.  It should be changed to:
                Assert("Build exception should have been because of a
recursive include.\n" + e.ToString(), e.ToString().IndexOf("Recursive
includes are not allowed.") != -1);

By the way, in general, exception.ToString() is the preferred way of getting
string output from an exception -- rather than using the Message property.
This facilitates creating subclasses of Exception (or ApplicationException)
that will display more understandable error information that may not be
included in the exception's message.

cheers,
owen.



-------------------------------------------------------
In remembrance
www.osdn.com/911/
_______________________________________________
Nant-developers mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nant-developers

Reply via email to