Why Does GetBaseException Ignore InnerException's GetBaseException

G

Guest

First let me say that I understand that Asp.Net wraps my exception in an
HttpUnhandledException. I have found a lot of discussion about that on the
web, which was informative, but not helpful. Let me explain how my question
is different.

Second, let me say that I have two questions. One is an ASP.Net related
question. The other is a general System.Exception question. They are related
but also individual.

Okay here is my problem...

I have an ADO wrapper library. I use it to wrap provider-specific exceptions
with my own. For example when a opening a connection fails, my library has
its own exception that it throws. Consumers of my library don't know if it
was an Oracle connection that failed, an SqlClient connection that failed,
etc. However just in case, I do put the original ADO provider's exception in
the *innerException* property of my library's exception.

When an exception is thrown by my library, and not handled in the aspx page,
IIS displays the default error screen, which is fine. But it displays the
*inner-most* exception. So in this case, instead of displaying my library's
exception, it displays the provider's exception, which I had put into my
library's exception's innerException property. This is not what I want. I
don't want consumers of my library to see the provider exception unless they
really want to.

Like I said at the top of my post, I understand that it would not display
the outer-most exception. That would be the HttpUnhandledException. But I
don't understand why it drills down to the inner-most exception.

So I started poking around...

I stopped populating my library's exception's innerException. Now IIS
displayed my exception just like I wanted. When there is no innerException,
IIS displays my exception.

I wondered if there was something special about the provider exception that
made IIS want to display it, instead of displaying mine. So I populated my
library's exception's innerException with a new dummy exception. IIS still
displayed the inner-most exception.

Feeling frustrated I wondered if GetBaseException was being called. So I
overrode it. *Success!* If I return a new dummy exception from my library's
overridden GetBaseException method, that is what shows up in IIS. So clearly,
yes, IIS is showing the inner-most exception.

Why does IIS take it upon itself to decide that the inner-most exception
should be displayed? This makes me mad. Why would I wrap one exception inside
another if I don't want the outer exception to be exposed to the world? I
fully understand that IIS does not want to display the outer-most exception
(the httpUnhandledException).

Thinking, I override GetBaseException to return "me" (c# syntax "this"). It
doesn't work. I'm not sure what is going on. When I am not sure what is going
on I always turn to my trust friend the .Net Reflector!
(http://www.aisto.com/roeder/dotnet/). Sure enough take a look at this little
method known as System.Exception.GetBaseException()...

Public Overridable Function GetBaseException() As Exception
Dim exception1 As Exception = Me.InnerException
Dim exception2 As Exception = Me
Do While (Not exception1 Is Nothing)
exception2 = exception1
exception1 = exception1.InnerException
Loop
Return exception2
End Function

Notice anything funny? It does *not* call the innerExceptions's
GetBaseException. It just starts drilling down on *it's own* through the
InnerExceptions directly. Why doesn't it call the InnerException's
GetBaseException? That wouldn't be recursion exactly, but it would make more
sense to me. As it stands, overriding GetBaseException only works when you
are the outer-most exception. If the overriding exception gets wrapped up as
an inner exception (say for example in an HttpUnhandledException, as in this
case) all your precious overridden GetBaseException logic is *out the window*.

So I have two questions...

1) Why does IIS display the GetBaseException of the HttpUnhandledException
instead of the InnerException?

2) Why does System.Exception.GetBaseException drill down on its own through
the InnerExceptions, instead of honoring the possibly overridden
GetBaseExceptions?

Any information, education, guidance, or I-feel-your-pains would be greatly
appreciated.

John DeHope

p.s. I also posted this on the dotnet.framework.asp forum due to the dual
nature of the questions.
 
B

Barry Kelly

JohnDeHope3 said:
Why does IIS take it upon itself to decide that the inner-most exception
should be displayed? This makes me mad.

It makes me mad when I see a "TargetInvocationException". Each to his
own, I guess.
p.s. I also posted this on the dotnet.framework.asp forum due to the dual
nature of the questions.

If you want to post a question in multiple newsgroups, I suggest you
crosspost - i.e. put both newsgroups in the "Newsgroups" header. That
way, software can detect the crosspost. The alternative, multiposting
(i.e. what you've done), leads to people not being aware that the
question could have been satisfactorily answered in another newsgroup.

-- Barry
 
G

Guest

Thanks Barry, I'll do that next time. I was afraid to use the textbox for
cross posting because I wasn't sure I'd get the text of the newsgroup name
just right. I'll have faith next time and try it.

I can see how it'd be frustrating if somebody wraps an exception and you
didn't want it to be wrapped. But I *want* my exception wrapped.

Somebody in the asp newsgroup quoted the docs, explaining that the
overridable GetBaseException is for formatting exceptions, not for altering
the behavior of the base method. So I shouldn't be poking around in there. I
get that now. So my only beef is with asp/iis displaying an exception other
than the one I raised.
 
L

Luc E. Mistiaen

Maybe you can try to catch all exceptions in your application and resignal
your own exception that would then be the end of the chain. In order not to
loose the original chain of exception, you can stash it in your exception
has another property. Something along the lines

class MySpecialException : Exception
{
private Exception _OriginalException ;
public OriginalException {get {return _OriginalException ;}}
public MySpecialException (string Message, Exception e) : base (Message)
{_OriginalException = e ;}
}
.....
in your application
....
catch (Exception e) {throw new MySpecialException ("My Special Text", e) ;}
....


/LM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top