Main Method Code Entirely Inside Try/Catch: Is It Bad Practice

Main method code entirely inside try/catch: Is it bad practice?

Wrapping any piece of code in a try/catch block without a good reason is bad practice.

In the .NET programming model, exceptions should be reserved for truly exceptional cases or conditions. You should only try to catch exceptions that you can actually do something about. Furthermore, you should should hardly ever catch the base System.Exception class (but rather prefer to catch the more specific, derived exception classes you can handle). And should a truly unexpected exception be encountered during the course of your program's execution, you actually should crash.

Obviously the "correct" answer would have to be made on a case-by-case basis, depending on what's going on inside that // code placeholder in your catch block. But if you're asking for a general rule or "best practice", you should always have a specific reason to catch exceptions, not just wrap all of your code in a giant try/catch block as a matter of course without thinking about it.

Note that if you're simply trying to catch any unhandled exceptions that might occur for the purposes of logging or error reporting, you should be using the AppDomain.UnhandledException event. This is a notification-only event, so it doesn't allow you to handle those exceptions, but it is the right place to implement your logging or error reporting functionality after your application has crashed.


EDIT: As I was catching up on my reading of Raymond Chen's excellent blog, "The Old New Thing", I noticed that he had recently published an article on a similar topic. It's specific to COM, rather than the .NET Framework, but the general concepts regarding error handling are equally applicable to both environments. I thought I'd share a couple of gems from the article here, in support of my [apparently quite controversial] opinion.

Historically, COM placed a giant try/except around your server's methods. If your server encountered what would normally be an unhandled exception, the giant try/except would catch it and turn it into the error RPC_E_SERVERFAULT. It then marked the exception as handled, so that the server remained running, thereby "improving robustness by keeping the server running even when it encountered a problem."

Mind you, this was actually a disservice.

The fact that an unhandled exception occurred means that the server was in an unexpected state. By catching the exception and saying, "Don't worry, it's all good," you end up leaving a corrupted server running.

[ . . . ]

Catching all exceptions and letting the process continue running assumes that a server can recover from an unexpected failure. But this is absurd. You already know that the server is unrecoverably toast: It crashed!

Much better is to let the server crash so that the crash dump can be captured at the point of the failure. Now you have a fighting chance of figuring out what's going on.

You can [and should] read the whole article here on his blog: How to turn off the exception handler that COM "helpfully" wraps around your server.

Why are try-catch in main() bad?

I don't think its necessarily bad practice. There are a few caveats however...

I believe the point of whoever called this "bad practice" was to reinforce the idea that you should be catching exceptions closest to where they occur (i.e. as high up the call stack as possible/appropiate). A blanket exception handler isn't typically a good idea because its drastically reduces the control flow available to you. Coarse-grained exception handling is quite importantly not a reasonable solution to program stability. Unfortunately, many beginner developers think that it is, and take such approaches as this blanket try-catch statement.

Saying this, if you have utilised exception handling properly (in a fine-grained and task-specific manner) in the rest of your program, and handled the errors accordingly there (rather than juist displaying a generic error box), then a general try-catch for all exceptions in the Main method is probably a useful thing to have. One point to note here is that if you're reproducably getting bugs caught in this Main try-catch, then you either have a bug or something is wrong with your localised exception handling.

The primary usage of this try-catch with Main would be purely to prevent your program from crashing in very unusual circumstances, and should do hardly any more than display a (vaguely) user-friendly "fatal error" message to the user, as well as possibly logging the error somewhere and/or submitting a bug report. So to conclude: this method does have its uses, but it must be done with great care, and not for the wrong reasons.

Use Try-Catch to handle seen errors, is it bad?

Yes, this is bad practice, because throwing and catching exceptions is quite expensive, and exceptions should not be used for regular operation, only for error handling.

The preferred way to go about this, is to check whether the object is null yourself and handle that case appropriately.

Enclosing service execution in try-catch: bad practice?

That depends on what you are doing. If you intend to treat exceptions and do something useful with them (e.g. retry, run a backup, notify the user and ask for feedback etc) then IMO I do not think this is a bad practice.

As I said, it depends on what you are doing.

Should I always wrap my code in try...catch blocks?

Exceptions can occur about anywhere, so this made me think: should I always wrap my code in try..catch blocks?

Good question. Here's a related question:

Axe-wielding maniacs can be just about anywhere, so: should I wear axe-resistant body armor 24 hours a day?

I am fortunate to live in a neighborhood where the number of axe-wielding maniacs is sufficiently low that I don't wear armor when I leave the house. But suppose I did not. Is the right solution to wear the armor all the time or to jail the maniacs?

If your programs throw so many exceptions that you need to be handling those exceptions everywhere, then you have a big problem. The solution to that problem is not to armor up and put exception handling everywhere. The solution to that problem is to eliminate the code that is throwing the exceptions, and if you cannot eliminate it, then isolate it to a tiny region of code that does use exception handling.

Why should I not wrap every block in try-catch?

A method should only catch an exception when it can handle it in some sensible way.

Otherwise, pass it on up, in the hope that a method higher up the call stack can make sense of it.

As others have noted, it is good practice to have an unhandled exception handler (with logging) at the highest level of the call stack to ensure that any fatal errors are logged.

Thorough use of 'if' statements or 'try/catch' blocks?

this debate (2003) was good:

http://www.joelonsoftware.com/items/2003/10/13.html

http://nedbatchelder.com/blog/200310/joel_on_exceptions.html



Related Topics



Leave a reply



Submit