.NET Forum / .NET Framework / New Users / January 2008
Unhandled exception in class library
|
|
Thread rating:  |
raju - 22 Jan 2008 07:13 GMT 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 - 22 Jan 2008 08:10 GMT > 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 [quoted text clipped - 3 lines] > class library. Even though, if i got the error in any place of my > code. 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 - 22 Jan 2008 10:06 GMT On Jan 22, 1:10 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com> wrote:
> > 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 [quoted text clipped - 16 lines] > > Pete Hai,
thanks for your immd. reply.
My requirement is, in my "class library", if i forget the "exception handler" in any one of the place, where we can expect 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
Cezary Nolewajka - 22 Jan 2008 10:51 GMT 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-aga inst-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> wrote:
> > 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 [quoted text clipped - 16 lines] > > Pete Hai,
thanks for your immd. reply.
My requirement is, in my "class library", if i forget the "exception handler" in any one of the place, where we can expect 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 - 22 Jan 2008 10:55 GMT 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
On Jan 22, 1:10 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com> wrote:
> > 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 [quoted text clipped - 16 lines] > > Pete Hai,
thanks for your immd. reply.
My requirement is, in my "class library", if i forget the "exception handler" in any one of the place, where we can expect 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 - 22 Jan 2008 18:51 GMT > My requirement is, in my "class library", if i forget the > "exception handler" in any one of the place, where we can expect the > exception. That exception should be logged in to a text file, instead > of stop the execution. 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 - 26 Jan 2008 03:04 GMT On Jan 22, 11:51 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com> wrote:
> > My requirement is, in my "class library", if i forget the > > "exception handler" in any one of the place, where we can expect the [quoted text clipped - 66 lines] > > Pete 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 - 26 Jan 2008 04:18 GMT > Any unhandled exception throw by a class library can be caught in the > Appdomain's UnhandledException event. 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.
> Register for this event in the main. like so > [quoted text clipped - 3 lines] > to process the exception gracefully without effecting your > application. Absolutely not. The event will provide you with the information that the 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 would have made the application terminate, then even with the event being handled the application is still going to terminate.
> You can write code to log the exception in the file if you so desire > in the event handler. 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 - 26 Jan 2008 14:33 GMT 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 - 26 Jan 2008 15:07 GMT > 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. 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 - 26 Jan 2008 18:26 GMT > 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. 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 - 27 Jan 2008 17:43 GMT 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. -----------------------------------------------
>> Ok here is another observation.. >> [quoted text clipped - 30 lines] > > Pete Peter Duniho - 27 Jan 2008 18:54 GMT > 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? 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.
> 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? 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.
> 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? 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 - 28 Jan 2008 02:29 GMT >> 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 [quoted text clipped - 87 lines] > > Pete 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 - 28 Jan 2008 03:06 GMT > 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. 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
John Saunders [MVP] - 22 Jan 2008 10:48 GMT > Hello, > [quoted text clipped - 8 lines] > How to catch these type of unhandled exception from my class > library. 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 } }
 Signature -------------------------------------------------------------------------------- John Saunders | MVP - Windows Server System - Connected System Developer
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|