13 Replies - 6098 Views - Last Post: 15 June 2010 - 02:42 AM

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Discussion - Exception handling in C#

Post icon  Posted 08 June 2010 - 08:29 PM

Along the same vane(sp) as Get it working versus get it working the right way, we're going to discuss proper exception handling in .Net, specifically C# (well since this is the C# Programmers forum).

Exception handling in programming is an essential piece, necessary to keep our applications from puking all over the place (we've all had it happen at least once in our career and it's not fun to read that email or field that call). Fortunately C# (.Net Framework) offers us a nice mechanism for exception handling, structured exception handling.

Exceptions are reporting mechanisms for providing information about the error that occurred, and when dealing with error checking & exception handling the more you can gather the better off you are (whether it be an unexpected, unhandled exception, or a caught/thrown exception). The Exception class offers the following properties (these are the most utilized anyways, there are more that can be found here)

  • Message: Holds the actual message from the exception.
  • Source: What application/object did the exception occur in.
  • TargetSite: The method that threw the exception.
  • StackTrace: The actual call stack of the exception


Ok enough describing what C# has to offer for exception handling, let's take a look at some points that should always be remembered when exception handling:

  • Use a single try with multiple catch blocks: It's always better to have one try statement with many/multiple catch statmeents for handling different exception typed.
  • Order catch blocks in proper order If you use multiple catch blocks always place them in the proper order: From most specific to most general exceptions. This makes it clearer when coming back to your code or when someone else is reading your code.
  • Always come back to a valid state: Always make sure you get into a valid state, make sure the application can move forward and no severe side effects have occurred from the exception before moving forward.
  • When throwing, throw closest matching exception: Make sure, when throwing an exception, that you pick the exception that closet resembles what has taken place, especially in situations where more than one exception can describe what has just happened.
  • Extend Application not System.Extension: When creating your own custom exceptions always extend the ApplicationExtension class, this will help keep your exceptions in a different hierarchy.
  • When rethrowing always use InnerException: This will help keep the inner cause of the initial exception in tact, especially with linked/nested exceptions.


Now that I have my spiel out of the way, what best practices do you require yourself and other developers to stick by when it comes to exception handling in your C# applications. While my list is by no means exhaustive I feel those are at the top of my list to adhere to when handling exceptions

Is This A Good Question/Topic? 3
  • +

Replies To: Discussion - Exception handling in C#

#2 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Discussion - Exception handling in C#

Posted 08 June 2010 - 10:05 PM

I need to add something to this

  • Have an exception logging module: They're pretty easy to write and can prove invaluable down the road when Client A says he was doing Functionality Y and got an error but cannot remember exactly what it said. Look through your exception log and you can find out what he was doing, where he was at when it happened and find out exactly what went wrong.

    Add it to your structured exception handling, just log the exception when it's caught or thrown. Trust me will will prove to be an invaluable tool down the road as your application and user base grows.

    Even if it's just a simple one off application for a client, implement some sort of exception logging in that as well, even if it's just XML based and logs everyt exception that is registered.

Was This Post Helpful? 1
  • +
  • -

#3 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Discussion - Exception handling in C#

Posted 09 June 2010 - 02:34 PM

Compared to other languages that I've used in the past, the .NET languages have by far the best exception handling I have ever used. For a long time the programmer had an extremely hard time making sure that their programs worked as expected when the user did something unexpected, ie typed in a string when a number was expected. This can still be problematic in different languages.

Unexpected input is probably one, if not the biggest, problem that a programmer faces. For all numeric types, int, float, double, etc. Microsoft did us one big favor. They included the TryParse method for dealing with unexpected input when dealing with numeric conversions. There is a little overhead that goes with the try-catch-finally block. As programmers, you shouldn't always rely on that. You should also try and write your program to prevent it from throwing an exception in the first place. You should try and limit exception handling to critical code that must preform as excpected and if it doesn't recover gracefully.

Just my feeling on the subject, but I grew old school. I began long before .NET and then you had to write better code from the get go. You couldn't rely on the beauty that C# has given us to recover. C# is safe code. You can get in a lot less trouble than you can with other languages.
Was This Post Helpful? 0
  • +
  • -

#4 Guest_Pablo Montilla*


Reputation:

Re: Discussion - Exception handling in C#

Posted 09 June 2010 - 07:24 PM

Good post, but please it is a bad practice (per BCL best practices) to derive exception classes from ApplicationException.

See the Brad Adams post (old but goodie :).

Regards,
Pablo
Was This Post Helpful? 0

#5 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Discussion - Exception handling in C#

Posted 09 June 2010 - 10:30 PM

@Guest_Pablo Montilla I'll have to respectfully disagree with this statement

Quote

but please it is a bad practice (per BCL best practices) to derive exception classes from ApplicationException


That's good practice, bad practice is deriving all your custom extensions from the System.Extension. There is far too documentation out there (and I'll find it tomorrow for you, so the blinders can be lifted). Main reason for doing it the right - inherit from ApplicationException is so your custom extensions in a different hierarchy, which is where you want them
Was This Post Helpful? 0
  • +
  • -

#6 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Discussion - Exception handling in C#

Posted 10 June 2010 - 05:56 AM

From the Microsoft Documentation "For most applications, derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value."

Not sure when this was changed, but this is the .NET 4.0 docs.


What I hate to see people do with Exceptions is use them as flow control.

This post has been edited by Momerath: 10 June 2010 - 06:04 AM

Was This Post Helpful? 3
  • +
  • -

#7 demausdauth  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 177
  • View blog
  • Posts: 641
  • Joined: 03-February 10

Re: Discussion - Exception handling in C#

Posted 12 June 2010 - 05:06 PM

View PostMomerath, on 10 June 2010 - 05:56 AM, said:

What I hate to see people do with Exceptions is use them as flow control.


I have seen this so many times that it makes me cringe.
Was This Post Helpful? 0
  • +
  • -

#8 Yakyb  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 21
  • Joined: 04-June 08

Re: Discussion - Exception handling in C#

Posted 14 June 2010 - 04:33 AM

View PostMomerath, on 10 June 2010 - 04:56 AM, said:

What I hate to see people do with Exceptions is use them as flow control.


sorry i'm not entirely sure what you mean by this
Was This Post Helpful? 0
  • +
  • -

#9 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Discussion - Exception handling in C#

Posted 14 June 2010 - 05:42 AM

View PostYakyb, on 14 June 2010 - 02:33 AM, said:

View PostMomerath, on 10 June 2010 - 04:56 AM, said:

What I hate to see people do with Exceptions is use them as flow control.


sorry i'm not entirely sure what you mean by this


try {
    while (someCondition) {
        foreach (Sometype i in j) {
            DoSomeStuff();
            if (someOtherCondition) {
                throw MyException // I want to break out of the while loop here
                                  // and 'break' would just leave the foreach loop
            }
            MoreStuff();
        }
        SomeOtherCodeIDontWantToRunWhenIBreakTheWhileLoop();
    }
} catch (Exception e) {
} finally {
    CodeToRunAfterTheWhileLoop();
}

Was This Post Helpful? 0
  • +
  • -

#10 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,636
  • Joined: 16-October 07

Re: Discussion - Exception handling in C#

Posted 14 June 2010 - 06:16 AM

I'm not sure I buy the ApplicationException thing. I understand the reasoning behind it. However, it's my custom exception, that only my program can handle anyway. It's already adequately categorized by virtue of being in my program's namespace. Perhaps if there was some specialized processing benefit that applied to that parent class, but it really sounds like an idea without any practical application.

I would add to the list: Keep your try catch block small. That is, put the code inside that has the possibility of throwing the exception. If simply initializing constructs doesn't, don't put them in there.

View PostMomerath, on 10 June 2010 - 06:56 AM, said:

What I hate to see people do with Exceptions is use them as flow control.


Agreed.

Someone asked for example, it would look like this:
// exceptions as flow control
Console.Write("Please enter a number between 1-100: ");
try {
	int value = int.Parse(Console.ReadLine());
	if (value < 1) { throw new System.ArgumentException("Value cannot be less than 1."); }
	if (value > 100) { throw new System.ArgumentException("Value cannot be greater than 100"); }
	Console.WriteLine("The square of {0} is {1}.", value, value * value);
} catch (System.FormatException) {
	Console.WriteLine("Value must be a number.");
} catch (System.ArgumentException ex) {
	Console.WriteLine(ex.Message);
}



In reality, you don't need exceptions here at all. The flow can be handled by simple logic.
Console.Write("Please enter a number between 1-100: ");
int value;
if (!int.TryParse(Console.ReadLine(), out value)) {
	Console.WriteLine("Value must be a number.");

} else if (value < 1) { 
	Console.WriteLine("Value cannot be less than 1."); 

} else if (value > 100) { 
	Console.WriteLine("Value cannot be greater than 100"); 

} else {
	Console.WriteLine("The square of {0} is {1}.", value, value * value);
}



It's often tempting to throw an exception as a kind of exiting goto. However, there's overhead with exceptions. You want to use them when you need to, when dealing with "exceptional" circumstance you have no control over. If you can handle such circumstances through simple constraint checking, that's always the better option.
Was This Post Helpful? 0
  • +
  • -

#11 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Discussion - Exception handling in C#

Posted 14 June 2010 - 11:57 AM

As far as ApplicationException over Exception, this was an excerpt I went by initially in my .Net days but things have indeed changed (so I stand corrected Momerath)

Quote

“ApplicationException is thrown by a user program, not by the common language runtime. If you are designing an application that needs to create its own exceptions, derive from the ApplicationException class. ApplicationException extends Exception, but does not add new functionality. This exception is provided as means to differentiate between exceptions defined by applications versus exceptions defined by the system.”


But ApplicationException is being deprecated and I was unaware of this (see how long it's been since I did any work creating custom exceptions) so I will amend my initial post in this thread to represent that change
Was This Post Helpful? 0
  • +
  • -

#12 Frinavale  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 203
  • View blog
  • Posts: 776
  • Joined: 03-June 10

Re: Discussion - Exception handling in C#

Posted 14 June 2010 - 12:30 PM

Using Try-Catch blocks to handle exceptions is a great way to keep your code from spilling out error message details that the end user will be confused about. I strongly recommend using them; however, there are situations where allowing an exception to be thrown out of your code's scope is a good thing.

For example, say you have developed a class library that is called upon by another piece of software to do something. If your software catches all Exceptions and then closes nicely, the calling code will have no idea what went wrong.

So, I strongly discourage code that looks like this:
(C#)
try{
  //do something that causes an error
}catch(Exception ex){
  //do nothing.
}


Catching all Exceptions thrown by a piece of code for the sake of hiding errors from users, in this case, is a Terrible thing. There is nothing worse than trying to use a DLL (class library) that dies with no explanation for why! I've seen this implemented and trying to fix the problem was a nightmare.

If you are developing a class (or class library) I recommend that you allow Exceptions that you are not going to handle to pass up to the calling code so that it may take the appropriate action.

Another thing, that has already been mentioned, is that there is some overhead with the creation of Exceptions. To create more efficient code I recommend that you try to test for conditions that you are expecting to cause problems before you cause the problem...so that you can avoid this overhead in the first place.

I also agree that Exception driven applications are disgusting (even though they work). Exceptions are meant to be a way to determine what is causing errors, they are not meant to be running the application!

-Frinny

This post has been edited by Frinavale: 14 June 2010 - 01:02 PM

Was This Post Helpful? 1
  • +
  • -

#13 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Discussion - Exception handling in C#

Posted 14 June 2010 - 12:50 PM

View PostFrinavale, on 14 June 2010 - 10:30 AM, said:

For example, say you have developed a class library that is called upon by another piece of software to do something. If your software catches all Exceptions and then closes nicely, the calling code will have no idea what went wrong.

So, I strongly discourage code that looks like this:
(C#)
try{
  //do something that causes an error
}catch(Exception ex){
  //do nothing.
}


I completely agree! Granted, there are actually exceptions to this rule, where it's a good thing to swallow an exception (I recently had to do this in an application). Now let's see who's going to flame for this practice. To clarify why I did this, it was a class that would get all running processes and display them on a form (there's a tread somewhere here on DIC where I asked about it) and some processes (rare case) would always throw an exception on Windows 7 and the best way we came up with to get around this is to just swallow the exception and move on.

I didnt use

Try
{

}
catch(Exception ex)
{

}



I used
try
{

}
catch
{

}



Here's the code in question

public List<Proc> GetRunningProcesses()
{
    PerformanceCounter c = new PerformanceCounter();
    Process[] processes = Process.GetProcesses();
    List<Proc> running = new List<Proc>();
    
    try
    {
        foreach (Process process in processes.Where(
            process =>
            {
                bool hasException = false;
                try 
                { 
                    IntPtr x = process.Handle; 
                }
                catch 
                { 
                    hasException = true; 
                }
                return !hasException;
            }))
        {
            c.CategoryName = "Process";
            c.CounterName = "% Processor Time";
            c.InstanceName = process.ProcessName;
            float cpu = c.NextValue();

            string priority = "Normal";

            switch (process.BasePriority)
            {
                case 13:
                    priority = "High";
                    break;
                case 4:
                    priority = "Idle";
                    break;
                case 8:
                    priority = "Normal";
                    break;
                case 24:
                    priority = "Real Time";
                    break;
            }

            running.Add(
                new Proc
                {
                    ProcessID = process.Id,
                    ProcessName = process.ProcessName,
                    ProcessThreads = process.Threads.Count,
                    ProcessMemory = CoreUtilities.FormatBytes(process.PrivateMemorySize64),
                    ProcessStartTime = process.StartTime.ToShortTimeString(),
                    ProcessPriority = priority,
                    ProcessCpuUsage = cpu
                });
        }
        running.Sort
            (
                delegate(Proc proc1, Proc proc2)
                {
                    return proc1.ProcessName.CompareTo(proc2.ProcessName);
                }
            );

    }
    catch
    {
        //swallow and move on
    }
    return running;
}


While using an empty catch can be called bad practice it worked for what I needed. While 99% of the time I strongly disagree with swallowing an exception, there are rare cases where it's Ok to do so (Just like there's rare cases where it's Ok to use the Singleton Design pattern)
Was This Post Helpful? 0
  • +
  • -

#14 Ace26  Icon User is offline

  • D.I.C Head

Reputation: 40
  • View blog
  • Posts: 183
  • Joined: 10-August 08

Re: Discussion - Exception handling in C#

Posted 15 June 2010 - 02:42 AM

For me, first of all I check user input by using the ErrorProvider component. Then for every microsoft provided class I use I look up the documentation for every possible exceptions that might occur and catch them first then generally catch any exception of any kind.

I recently started using logging functionalities in my apps to be able to detect the history of exceptions and all-what-nought that occur during its runtime and I can't overly emphasize how wonderful the outcome has been!

This post has been edited by Ace26: 15 June 2010 - 03:09 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1