.NET Framework - Unhandled exception in class library

Asked By raju on 06-Feb-08 05:45 AM
Hello,

I am creating one class library in .net. I need to save the
unhandled exception in a text file. So how to catch the unhandled
exception from class library.

Unhandled exception means, i am having try.. Catch  block in my
class library. Even though, if i got the error in any place of my
code.

How to catch these type of unhandled exception from my class
library.

Regards,
Raj.




Peter Duniho replied on 22-Jan-08 03:10 AM
I don't understand the question.  If you have a try/catch block and you're
catching the exception, doesn't that mean that the exception was handled?
And assuming you've got a try/catch block that's catching the exception,
what's the problem?  Can't you use the Exception that's caught for logging
to a text file?

Could you rephrase the question to clarify those issues?  It might be
helpful for you to post a little code sample demonstrating the
relationship between the code that throws an exception and how you want to
handle it.

Pete
raju replied on 06-Feb-08 05:45 AM
On Jan 22, 1:10=A0pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
n my
re =A0
=A0
=A0
ng =A0
=A0
=A0

Hai,


thanks for your immd. reply.

My requirement is, in my "class library", if i forget the
exception. That exception should be logged in to a text file, instead
of stop the execution.

eg.,

namespace ECommerce{

public class CardProcessor{

public void MethodCaller(){
CalledMethod();
}

public void CalledMethod(){
throw new Application("Error Raised");
}

}
}

If i used this class library in my project, what will happen? I
am thinking that, it will stop the execution. If my thinking is
correct, then it would not stop the execution, instead of that, the
error will be logged in a text file.

I think, now you will understand my requirement.

Regards,
Raj
John Saunders [MVP] replied on 22-Jan-08 05:48 AM
In general, this is not a good design pattern. The class library shouldn't
be catching exceptions just to log them - the caller should be catching
them, if it wants to.

Otherwise, you'll need to put a try/catch block around the body of every
public method or property in your class library. There's no way to create a
library-wide exception handler. Something like this:

public void Method()
{
try
{
// body of the code
}
catch (Exception ex)
{
// log the exception here
}
}
--
--------------------------------------------------------------------------------
John Saunders | MVP - Windows Server System - Connected System Developer
Cezary Nolewajka replied on 22-Jan-08 05:51 AM
In my understanding you would like to catch all exceptions that might
happen, log them, even if you forget try/catch block.

As far as I know, there is no general error handling if an exception is
thrown. You need to have a try/catch for that in every routine you expose
from your class library.

On top of that, I would mention, that it's generally NOT recommended to
handle ALL exceptions. You should handle only those exceptions you KNOW how
to handle properly. All other should propagate up the call stack. If you
would like to log them, then maybe an idea would be to call them and rethrow
after logging.

A nice discussion of exception handling in the above context is here:

http://blogs.msdn.com/fxcop/archive/2006/06/14/FAQ_3A00_-Why-does-FxCop-warn-against-catch_2800_Exception_29003F00_-_2D00_-Part-1-_5B00_Nick-Guerrera_5D00_.aspx

Best regards,
Cezary Nolewajka

Consultant | Microsoft Services | Microsoft | Poland

On Jan 22, 1:10 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>

Hai,


thanks for your immd. reply.

My requirement is, in my "class library", if i forget the
exception. That exception should be logged in to a text file, instead
of stop the execution.

eg.,

namespace ECommerce{

public class CardProcessor{

public void MethodCaller(){
CalledMethod();
}

public void CalledMethod(){
throw new Application("Error Raised");
}

}
}

If i used this class library in my project, what will happen? I
am thinking that, it will stop the execution. If my thinking is
correct, then it would not stop the execution, instead of that, the
error will be logged in a text file.

I think, now you will understand my requirement.

Regards,
Raj
Patrice replied on 22-Jan-08 05:55 AM
I would suggest rather :
- each application should have a global exception handler that is
responsible to handle exceptions not handled locally (wether or not it comes
from itself or from third party libraries)

If you do what you want (not sure you can have a class library level
exception handler anyway) :
- your application will continue if you have an error. It could make things
worse
- you'll hide errors from the application that has no choice about how to
handle those hidden exceptions
- you'll hide also them from the developper that will have to check this
file for errors

IMO a class library should :
- handle exceptions for which you *really* know you can do something or to
clean up resources (but still let the exception to be propagated to the
caller)
- tihis is not the class library job to deal with legitimate exceptions that
could happen. IMO this is the job of the main application (using a global
exception handler as a safety net and possibly local exception handler where
appropriate)...

--
Patrice


98eab9e3-f4f0-45b9-b4c3-ad50d59979c0@e4g2000hsg.googlegroups.com...
On Jan 22, 1:10 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>

Hai,


thanks for your immd. reply.

My requirement is, in my "class library", if i forget the
exception. That exception should be logged in to a text file, instead
of stop the execution.

eg.,

namespace ECommerce{

public class CardProcessor{

public void MethodCaller(){
CalledMethod();
}

public void CalledMethod(){
throw new Application("Error Raised");
}

}
}

If i used this class library in my project, what will happen? I
am thinking that, it will stop the execution. If my thinking is
correct, then it would not stop the execution, instead of that, the
error will be logged in a text file.

I think, now you will understand my requirement.

Regards,
Raj
Peter Duniho replied on 22-Jan-08 01:51 PM
You should definitely read the other replies...you've gotten three other
responses, all of which include good information.

That said, there's one possibility that doesn't seem to have been covered
explicitly, and which you _might_ be asking about.  That is, you're trying
to protect against your own errors, to catch exceptions that should not
have happened or which should have happened but which your own library
should have recovered from and didn't.

Now, this scenario doesn't change the other advice much.  But it's at
least a potentially more worthwhile goal than trying to catch all
exceptions.  After all, a good library will only throw an exception either
when the client code does something wrong, or when the library was asked
to do something that isn't possible and throwing an exception is a
well-defined response to that.  All the more reason to dissuade you from
doing it.  :)

The problem is that there's no global way to catch exceptions.  To prevent
a thread or process from being terminated due to an exception, you really
need to handle it.  There are "unhandled exception" events you can
subscribe to, but those don't catch exceptions...they just provide
notification of them and subscribing to the events won't prevent the
exception from causing what it would otherwise cause.

So you're still stuck putting exception handlers in every single one of
your public methods and properties for your library.  And in addition,
since there are going to be some exceptions that _should_ be allowed back
through to the client of the library, you need to include some mechanism
to distinguish between the two.  One mechanism for this might be to create
a new exception class (call it something like "PassthroughException") that
when caught at the top-level of the call chain in your library (i.e. one
of those public methods or properties) is a signal to that exception
handler that it _should_ rethrow the exception.

There are problems with this solution though.  One being that it means
none of your public methods or properties can themselves call another
public method or property.  The property question is especially
problematic, since using property accessors rather than the underlying
fields is desirable whether the code is the client code or the library
itself.  Another problem is that while you can rethrow the underlying
exception (set the inner exception when wrapping in your pass-through
exception, and then throw that inner exception again from the top-level
method or property), doing so will (if I recall correctly) rewrite the
stack trace for the exception, hiding useful information.

IMHO, the bottom line is that you really just need to make sure you don't
throw exceptions that are your fault.  As others have pointed out, if you
are handling these unexpected exceptions and writing them to a log file,
you're just sweeping bugs under the rug.  An unexpected exception is a
bug, and once one happens you have no way to know that you're not going to
cause something else to be wrong later on.  Data could wind up corrupted,
or the library could stop doing the right thing, or any number of other
things could go wrong.

So, in spite of the apparent usefulness of doing so, do pay heed to the
other advice given.  Don't handle an exception unless you can _truly_
handle it (and by that I mean, your code understands the exception and
knows what the appropriate response to it is).  Other exceptions, leave it
up to the client code to deal with, and preferably they should either
figure out how not to cause the exception to happen (in cases where their
code did something wrong) or they should tell you about the exception so
that you can fix the bug in your library that caused it (in cases where
your library did something wrong).

Pete
Amar replied on 06-Feb-08 05:46 AM
On Jan 22, 11:51 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>

Any unhandled exception throw by a class library can be caught in the
Appdomain's UnhandledException event.
Register for this event in the main. like so

AppDomain.CurrentDomain.UnhandledException += // event handler.

This will fire if any unhandled exception is thrown and will allow you
to process the exception gracefully without effecting your
application.
You can write code to log the exception in the file if you so desire
in the event handler.
Ope this is what you required
Peter Duniho replied on 25-Jan-08 11:18 PM
On Fri, 25 Jan 2008 19:04:31 -0800, Amar <amarjeetlokhande@gmail.com>  =



No, not really.  The event will be raised, but it in no way could be  =

considered as actually _handling_ the exception.  The exception remains =
=

unhandled.



Absolutely not.  The event will provide you with the information that th=
e  =

exception occurred, but otherwise it is just as if the exception was not=
=

handled.  It in no way allows you "to process the exception gracefully  =

without affecting your application".  For example, if the exception woul=
d  =

have made the application terminate, then even with the event being  =

handled the application is still going to terminate.


This is definitely a possible use of the event.  Keeping some record of =
=

what happened is certainly doable.  But that's a long way from actually =
=

_handling_ the exception and reacting to it in a useful way.

Pete
Amar replied on 06-Feb-08 05:46 AM
Ok I guess I did make a wrong choice of words.
this is what I meant ..
In the eventhandler of the unhandledThreadexception event, you can do
cleanup of your application and then exit voluntarily, instead of
causing an abrupt application termination.
Amar replied on 06-Feb-08 05:46 AM
Ok here is another observation..

If the class library that you are going to make is for a windows
application then use the Application.ThreadException, to avoid
crashing of your application.
Because  this event allows you to log the error occurred and continue
with the application(of course the code that caused the exception is
skipped, that is say the exception occurs in the middle of a loop,
then the loop is skipped, infact  no code on the execution path of
that thread is executed.).

But if the exception occurs in the constructor of the form, then this
event does not get fired. so Beware.

Say You have a form, and have a menu item on the form.
if you write the throw exception code in the constructor of the form,
ThreadException event in the Application class does not help, that is,
the application still terminates.
but if you write the throw exception code in the click event of the
menu item, then the application does not terminate, but returns to the
normal flow.
Peter Duniho replied on 26-Jan-08 01:26 PM
On Sat, 26 Jan 2008 07:07:40 -0800, Amar <amarjeetlokhande@gmail.com>


Just because you've avoided crashing at the point in time of the
exception, that doesn't mean that you've recovered safely.  In particular,
unless the exception handler has specific information about when, where,
and how the exception occurred, your program data is in an indeterminate
state.

ThreadException is only useful for dealing with exceptions that occur
during UI processing, first of all, so it's of limited utility.  If the
exception occurs just in some code that is only dealing with the specific
user input, without touching any data that has a lifetime longer than the
input event, you can avoid crashing the program without any long-term
risks.  But wouldn't it just be better to write code that doesn't generate
unhandled exceptions in the first place?

If the exception occurs in some library (that is, if it's a situation that
is actually relevant to this discussion thread), then you still have no
idea whether it's safe to continue after the exception or not.  Your data
could (and probably is) corrupted, and continuing at that point is just
going to cause more trouble.

IMHO it is very bad advice to suggest that any code that can only detect
exceptions globally can in any way be used to safely resume after an
exception.  In _some_ situations, you _may_ be able to at least log an
error and _possibly_ even save some data known to be uninvolved in the
exception.  But otherwise, at that point in execution, if you detect an
exception it is too late to recover from it.

Pete
RobinS replied on 27-Jan-08 12:43 PM
I agree that you should try to catch any exceptions you can. However, it's a
good idea to capture any unhandled exceptions so you can shut down your
application, rather than having the Microsoft dialog come up and tell the
user the app is no longer working, right?

So here's my question: What is the difference between handling the
AppDomain.CurrentDomain.UnhandledException and handling the ThreadException?
Should you handle both of them in your startup class? I thought the
ThreadException was to catch exceptions in background threads, but
apparently I'm wrong about that?

And when you do handle them, what do you do? Shut down any database
connections and run Application.ExitI() to exit your application? I think
you can't put any UI stuff in there, right?

Thanks,
RobinS.
GoldMail, Inc.
-----------------------------------------------
Peter Duniho replied on 27-Jan-08 01:54 PM
Well, I disagree.  This is a matter of philosophy -- I don't think there
are objective, unequivocable arguments in either direction -- but I don't
really see the advantage of one over the other, and my preference is that
the less code one writes, the less likely one is to write buggy code.

If I write some code, I want it to add some real value to the user.
Replacing the standard Microsoft "process terminating" dialog with one's
own doesn't seem to add any real value for the user.  In fact, while I
don't know the details my understanding is that Microsoft has a reporting
system tied to that dialog that, if you present your own dialog, you
completely shortcut.  I realize most software authors probably don't avail
themselves of the reporting system, but it's there nonetheless.

It's my feeling that if all you're going to do when you catch an exception
globally, or receive report of it via some event, is to shut down the
application then, well...Windows can shut down the application just as
well as you can.


It would probably be helpful to read the documentation pages for those
events.  I'd start with the high-level discussion of exceptions in managed
threads:
http://msdn2.microsoft.com/en-us/library/ms228965.aspx

And then of course look at the documentation for the specific events.

First, _neither_ event really "catches" exceptions.  They are events that
are raised when unhandled exceptions occur.  Generally, UnhandledException
is for dealing with exceptions in non-GUI threads, while ThreadException
is raised for exceptions in GUI threads.  Subscribing to ThreadException
does in fact change the behavior of the application if an unhandled
exception occurs, but it's still not really handling the exception.

Since I don't use either myself (see above regarding my philosophical bent
with respect to this issue :) ), I can't really offer much precise
discussion about the events.  But my understanding is that with
ThreadException, you can in fact suppress termination of the application
due to an exception raised during the processing of a window message if
you subscribe to the event.  With UnhandledException, it not being
relevant for GUI threads, this doesn't happen.  An exception in a non-GUI
thread will cause the application to terminate regardless.


You can theoretically try anything you want.  For ThreadException, since
the message pump hasn't been shut down, any UI stuff should work.  For
UnhandledException, you would need to start up a new message pump (either
explicitly, or by showing a dialog modally), but you could probably get
some UI to happen.

But why would you?  Shut down database connections?  Those will go away
soon enough once the process has been terminated.  How can you be sure you
can shut them down cleanly?  What if the exception occurred while you were
already trying to shut them down cleanly, and you had a bug in your code
that prevented that from happening correctly?

The problem with thinking that you can do something to recover from these
kinds of exceptions is that by definition, they were unexpected and you
have no reason to believe that _any_ of your data is in a consistent
state.  It could be that none of the data is corrupted, or it could be
that all of it is.  And heaven help you if your code's execution path
depends on the data (as is very commonly the case), which means that you
have no idea what code is safe to execute except that which is entirely
independent of your data (and what use would executing that code be?).

So, the best you can do is perhaps log an error to a file (a file
dedicated to the purpose of logging unexpected exceptions like this,
guaranteed to be unrelated to whatever exception occurred).  And in fact,
in some cases this is definitely a useful thing.  If you have a close
relationship with your users and they can be relied upon to provide such a
file and to discuss with you the nature of the exception, this sort of
thing can be very useful.

So, it's not that there's no use for this sort of global exception
handling.  It's just that I feel people should be realistic about what
sorts of things can be done when dealing with exceptions in a global way.
IMHO, recovery is not a likely option.

Pete
RobinS replied on 27-Jan-08 09:29 PM
Thanks for all of the information.

Just for your peace of mind, it is not my intention to recover from the
errors. I have logging in place, and I would like to log the exception
information and then exit the application, then I can get a copy of the log
file and see what the exception is. I don't think that is an unrealistic
expectation.

This would be especially helpful in the case of exceptions thrown in the
background threads, since it does not provide the opportunity to do any
logging, it just shuts down the app with no "saveable" indication of what
went wrong.

Thanks again,
RobinS.
GoldMail, Inc.
Peter Duniho replied on 27-Jan-08 10:06 PM
Nor I.  Sorry if that wasn't clear enough in my post.

Though, if you are using the same logging for the exception as you do for
other logging in the application, you should keep in mind the possibility
that you've arrived at your global exception handling as a result of an
exception that occurred while logging data elsewhere in the application.

It's best to keep whatever global exception processing exists completely
separate from other parts of the program.  But with that caveat in mind, I
do agree that logging errors is one of the few examples of situations in
which the global exception notification can be useful.

Pete