Click here to Skip to main content
15,887,135 members
Articles / Programming Languages / C# 5.0
Tip/Trick

State Management during Exception Handling

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
18 Jun 2014CPOL2 min read 7K   4  
Tips to manage state during exceptions

Introduction

The tip is aimed to put some light to manage the State of the application during erroneous conditions and exceptions.

Background

If you are writing Class library, which is going to be used by other developers, you should be very conscious while finalizing the approach for the Exception and Error Handling. Special attention is required to maintain the state of the type in all erroneous conditions.

Managing State during Exceptions

A thoughtful design highlights the following points to maintain the state during exceptional conditions:

Use of finally block to recover the state & to cleanup

finally blocks are the code blocks which are guaranteed to be executed in all conditions. finally blocks are so useful that C# compiler automatically inserts it in case of lock, using, foreach, etc. statements. It is primarily used for dispose of any object to avoid resource leak. In the following example, a fileStream is expected to be disposed of in all conditions and it's done in finally block.

C#
public sealed class ExampleClass {
    private void ExampleMethod() 
    {
        FileStream fs = new FileStream(@"C:\mv.txt ", FileMode.Open);
        try 
        {
            Console.WriteLine(100 / fs.ReadByte());
        }
        finally 
        {
// Put cleanup code in a finally block to ensure that the file gets closed
        if (fs != null) fs.Dispose();
        }
    }
}

Recovering from Exception

Spending few extra minutes with your code can help in identifying what all exceptions can be generated by that portion of code. By catching these special types of exceptions in separate catch blocks will help in handling the exception gracefully. For example in the following code, it’s quite obvious to have divided by zero Exception. Hence a special catch block is used to handle this specific condition.

C#
public class ExampleClass {

    private string ExampleMethod()
    {
        String result;
        FileStream fs = new FileStream(@"C:\mv.txt ", FileMode.Open);
        try 
        {
            Console.WriteLine(100 / fs.ReadByte());
        }
        catch (DivideByZeroException) {
                result = "Can Divide by zero"
        }
        catch (OutOfMemoryException) {
                result = "out of memory";
        }
        finally 
        {
    // Put cleanup code in a finally block to ensure that the file gets closed
        if (fs != null) fs.Dispose();
        }
        return result;
    }
}

Maintain State in Case of Unrecoverable Exception

In real life, a method calls many other methods to finish up any task. Some methods may succeed and some might fail. For example, let’s say that you’re serializing a set of objects to a disk file. After serializing 10 objects, an exception is thrown. As per exception handling guidelines, every exception is to be throw up to the caller. But what about the disk file state?
Obviously, the state is corrupt when exception occurred. To revert to original state of the disk file in this scenario, one has to back out of partially completed operation as shown in the example. To do this, we have to revert the disk file (in the example below) to the function beginning state.
Note: In this case, I am catching all and any exception and throwing it after recovering the state.

C#
public void SerializeObjectGraph(FileStream fs, IFormatter formatter, Object rootObj)
{    // Save the current position of the file.
    Int64 beforeSerialization = fs.Position;
    try {

    // Attempt to serialize the object graph to the file.
      formatter.Serialize(fs, rootObj);
    }
    catch { // Catch any and all exceptions.
    // If ANYTHING goes wrong, reset the file back to a good state.
      fs.Position = beforeSerialization;
    // Truncate the file.
       fs.SetLength(fs.Position);
    // NOTE: The preceding code isn't in a finally block because
    // the stream should be reset only when serialization fails.
    // Let the caller(s) know what happened by re-throwing the SAME exception.
       throw; 
    }
}

Points of Interest

In Exception Handling, it's worth noting that “throw e;” resets parameters like the Exception.StackWalk property whereas throw simply throws the same exception without resetting Exception.StackWalk.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --