user1215399
user1215399

Reputation: 85

C# Try-Catch & Exception handling

In various parts of code in a current project, there is constant usage of

try
{
    //code
}
catch(Exception e)
{
    //display nicely formatted error message
}

My question is, under the assumption that the code handles all known/assumed errors (such as checking if objects are null etc), should a try-catch be placed around the code that displays errors in a application-global format?

Or is it better practice to let the error throw an exception and have the application crash naturally?

Thanks

Upvotes: 0

Views: 10488

Answers (4)

Michael Edenfield
Michael Edenfield

Reputation: 28338

There are two distinct schools of thought here and proponents of both are often shocked and amazed that anyone could possibly believe the other way. In the end, it's a matter of preference and what your target user base is expecting and/or willing to accept, and more importantly, how well you know what your application does. (Your question implies that you didn't write all of the code involved, so that last bit might be trickier than you think.)

First of, I assume you are talking about an end-user application here, and not a class library. There is almost never a good reason to catch exceptions in a class library that you're not explicitly handling. You always leave that decision up to the callers.

In an end-user application, however, the decision is ultimately yours, as there isn't anyone higher up the call chain. In this case, you have two broad options:

Fail Fast

Some people believe that you are better off letting your application crash as soon as physically possible, when an error is encountered. While it seems a bit counter productive, keep in mind what it means to run into an unhandled exception: you literally have no idea what went wrong; even something as simple as your error logging code could behave in a way you aren't expecting.

If you are handling exceptions properly at the call sites, you should only receive this kind of 'unexpected' error when something really, really bad happens: out of memory, corrupted stacks, etc. The kind of thing you can't really recover from, no matter what, so there's no point in trying.

Fail Gracefully

Other people believe that you should try to isolate errors whenever possible, to keep your users from losing information. If your application is modular enough, its possible that a total failure in one area could have no effect at all on data in another area.

This is a riskier proposition: you have to be very careful not to leave yourself in an inconsistent state. It requires that you know, for sure, that nothing in the failing code is changing state from some other part of the code.

In Conclusion

As usual, the "right" answer is probably somewhere in the middle. In general, the risk of running in an inconsistent state is almost always a good reason to allow the application to die. Of course, you'll probably still want to do some level of logging here, which you can accomplish in a couple of ways. My preference is not to use exceptions for this, but to hook into the various "unhandled exception" events at the top level like this, this, or this. Log your exceptions in those event handlers, maybe display a "friendlier" error dialog, then let your application shut down. For example, we put something similar to this in the WPF applications we produce:

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             DispatcherUnhandledException="UnhandledException">


private void UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
    logger.FatalException("OH NOES! Bad stuff happened, bailing out.", e.Exception);
    MessageBox.Show("holy cow something bad happened:\r\n" + e.Exception.Message);
}

However, there are places where catching all exceptions might be safe; this is mostly limited to places where all of the data is going to be discarded no matter what. For example, printing or exporting the results of an already-completed operation might fail "safely", with no ill effects to the rest of the application. You probably wouldn't want your application to crash just because the user doesn't have a printer. (I have even run into cases with one third-party printing library where it explicitly threw System.Exception on error...) But you have to be very careful that you know what you're doing, and that your data is truly isolated from the rest of the system.

Upvotes: 2

Sandeep
Sandeep

Reputation: 7334

class PerformTask
{
    public void ConnectToDB(requiredParams)
    {


    }
}

class PerformTaskConsumer
{
   public void SomeMethod()
   {
      try
      {
         PerformTask obj = new PerformTask();
      }

      catch(RelaventExceptions)
      {

      }
   } 


}

Just avoid the exception if you can. If Exception occurs, leave it to the caller what he wants to do with the Exception. The caller may decide to show a well formatted message about the exception or decide to crash or what ever.

Eric Lippert has a good article regarding exceptions. here

Upvotes: 3

sergiogarciadev
sergiogarciadev

Reputation: 2202

A tip to you to know where to put the try ... catch block.

Put a global exception handler, to catch all exception not handled. Log the stack trace and exception, display a apologize to end user and CLOSE THE PROGRAM (never try to continue here).

Let the application run, when it crashes, check the reason and correct handle the exception with the most specific exception possible.

Remember: Exception are for exception, not for normal program behavior.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

Catching all exceptions like this is not a good practice, except at the top level of your application, where you display a nice error message. Done right, it could preserve end user's perception of your program as slightly buggy, but reasonable overall. In contrast, letting your application crash is the easiest way to convince your end users that your application is bad beyond repair.

As far as exception prevention goes, there are two major kinds of exceptions - programming errors (null pointer, class cast, out of range, etc.) and environment errors (file not found, network path is unavailable, user entry error, etc.) You can and should avoid the first kind, and be prepared to handle the second kind.

Upvotes: 6

Related Questions