Why not catch general Exceptions

Viewed 19021

My VS just told me;

Warning 2 CA1031 : Microsoft.Design : Modify 'Program.Main(string[])' to catch a more specific exception than 'Exception' or rethrow the exception.

Why should I do that? If I do so, and don't catch all exceptions to handle them, my program crashes with the all-popular report-screen. I don't want my users to get such error-crap!

Why should I not catch all exceptions at once to display a nice warning to the user saying: "Something went wrong, don't care about it, I will handle it, just be patient"?

Edit: Just saw I have a dupe here, sorry for that Dupe

Edit2: To clarify things; I do exit the program after any exception has been catched! I just don't want my user to see that "report to microsoft" dialog that show up when an unhandled exception is raised in a console-application!

12 Answers

I am all for catching specific known exceptions and handling state...but I use general catch exceptions to quickly localize problems and pass errors up to calling methods which handle state just fine. During development as those are caught, they have a place right next to the general exception and are handled once in release.

I believe one should attempt to remove these once the code goes into production, but to constantly be nagged during the initial code creation is a bit much.

Hence turn off (uncheck) the warning by the project settings as found in Microsoft.CodeQuality.Analyzers. That is found in the project settings under Code Analysis:

enter image description here

All answers are good here. But I would mention one more option.

The intention of author to show some fancy message is understandable. Also, default Windows error message is really ugly. Besides, if application is not submitted to "Windows Excellence Program" the developer will not receive information about this problem. So what is the point to use default runtime handler if it does not help?

The thing here is that default exception handler of CLR host ( https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/9x0wh2z3(v=vs.90)?redirectedfrom=MSDN ) works in a very safe way. The purpose of it is clear: log the error, send it to developer, set the return code of your process and kill it. The general way of how to change that is to write your own host. In this case you can provide your own way of handling exceptions.

Still, there is an easy solution which satisfies CA1031 and still most of your needs.

When catching the exception, you can handle it your own way (log, show the message etc) and at the end you can set the process result code and do the exit (using the mix of Thread.Abort and "Exit" methods, for example). Still, at the end of your catch block you can just put "throw;" (which will never be called because of ThreadAbortedException, but will satisfy the rule). Still there are some cases, like StackOverflowException, which can't be handled like that and you will see that default message box, for fixing which you need to fallback to custom CLR host option.

Additionally, just for your information, you application can run several threads (besides that one which execute Main method). To receive exceptions from all of them you can use AppDomain.UnhandledException. This event does not allow you to "mark" the exception as handled, still you can freeze the thread using Thread.Join() and then do the job (log, msgbox, exit) using another (one more) thread.

I understand all this looks a little tricky and may be not right, but we have to deal with the implementation of AppDomain.UnhandledException, ThreadAbortException, CorruptedState exceptions and default CLR host. All of this eventually does not leave us much of choice.

Related