Introduction
Software Programmers write code to
perform some desired actions. But every software may fail to perform
its desired actions under some of its internal or external failures.
The exception handling system in the C# language allows the
programmer to handle errors or anomalous situations in a structured
manner that allows the programmer to separate the normal flow of the
code from error-handling logic.
An exception can represent a variety of
abnormal conditions that arise from several possible external or
internal conditions of software application. External conditions of
execution failures includes, for example, network failures in
connecting to a remote component, inadequate rights in using a
file/system resource, out of memory exception or exception thrown by
a web service etc. These are mainly due to failures thrown by
environment components on which our application depends on e.g.
operating system, .net runtime or external application or
components. Internal failures may be due to software defects,
designed functional failures (failures required as per business
rules), propagated external failures e.g. a null object reference
detected by the runtime, or an invalid input string entered by a user
and detected by application code, user requesting to withdraw more
amount than the account balance(business rule).
Note: A must read
para is below
Code that detects
an error condition is said to throw an exception and code that
handles the error is said to catch the exception. An exception
in C# is an object that encapsulates various information about the
error that occurred, such as the stack trace at the point of the
exception and a descriptive error message. All exception objects are
instantiations of the System.Exception or a child class of it. There
are many exception classes defined in the .NET Framework used for
various purposes. Programmers may also define their own class
inheriting from System.Exception or some other appropriate exception
class from the .NET Framework.
Overview
There are three code definitions for exception handling. These are:- try/catch - Do something and catch an error, if it should occur.
- try/catch/finally - Do something and catch an error if it should occur, but always do the finally.
- try/finally - Do something, but always do the finally. Any exception that occurs, will be thrown after finally.
- FileNotFoundException
- IOException (base class of FileNotFoundException)
- SystemException (base class of IOException)
- Exception (base class of SystemException)
Examples
try/catch
The try/catch performs an operation and should an error occur, will transfer control to the catch block, should there be a valid section to be caught by:class ExceptionTest { public static void Main(string[] args) { try { Console.WriteLine(args[0]); Console.WriteLine(args[1]); Console.WriteLine(args[2]); Console.WriteLine(args[3]); Console.WriteLine(args[4]); } catch (ArgumentOutOfRangeException e) { Console.WriteLine(e.Message); } } }
class ExceptionTest { public static void Main(string[] args) { try { string fileContents = new StreamReader(@"C:\log.txt").ReadToEnd(); } catch (UnauthorizedAccessException e) // Access problems { Console.WriteLine(e.Message); } catch (FileNotFoundException e) // File does not exist { Console.WriteLine(e.Message); } catch (IOException e) // Some other IO problem. { Console.WriteLine(e.Message); } } }
try { int number = 1/0; } catch (DivideByZeroException) { // DivideByZeroException } catch { // some other exception }
try/catch/finally
Catching the problem is a good idea, but it can sometimes leave your program in an invalid state. For example, if you open a connection to a database, an error occurs and you throw an exception. Where would you close the connection? In both the try AND exception blocks? Well, problems may occur before the close is carried out.Therefore, the finally statement allows you to cater for the "in all cases do this" circumstance. See the example below:
using System; class ExceptionTest { public static void Main(string[] args) { SqlConnection sqlConn = null; try { sqlConn = new SqlConnection ( /*Connection here*/ ); sqlConn.Open(); // Various DB things // Notice you do not need to explicitly close the connection, as .Dispose() does this for you. } catch (SqlException e) { Console.WriteLine(e.Message); } finally { if (sqlConn != null && sqlConn.State != ConnectionState.Closed) { sqlConn.Dispose(); } } } }
using System; public class excepation { public double num1, num2,result; public void add() { try { Console.WriteLine("enter your number"); num1 = Convert.ToInt32(Console.ReadLine()); num2 = Convert.ToInt32(Console.ReadLine()); result = num1/num2; } catch(DivideByZeroException e) //FormatException { Console.WriteLine("{0}",e.Message); } catch(FormatException ex) { Console.WriteLine("{0}",ex.Message); } finally { Console.WriteLine("turn over"); } } public void display() { Console.WriteLine("The Result is: {0}",result); } public static void Main() { excepation ex = new excepation(); ex.add(); ex.display(); } }
try/finally
The try/finally block allows you to do the same as above, but instead errors that are thrown are dealt with by the catch (if possible) and then thrown up the call stack.class ExceptionTest { public static void Main(string[] args) { SqlConnection sqlConn = null; try { SqlConnection sqlConn = new SqlConnection ( /*Connection here*/ ); sqlConn.Open(); // Various DB bits } finally { if (sqlConn != null && sqlConn.State != ConnectionState.Closed) { sqlConn.Dispose(); } } } }
Re-throwing exceptions
Sometimes it is better to throw the error up the call stack for two reasons.- It is not something you would expect to happen.
- You are placing extra information into the exception, to help diagnosis.
How not to throw exceptions
Some developers write empty try/catch statements like this:try { // Do something } catch (Exception ex) { // Ignore this here }
Below is another example of how to incorrectly catch exceptions
/* Read the config file, and return the integer value. If it does not exist, then this is a problem! */ try { string value = ConfigurationManager.AppSettings["Timeout"]; if (value == null) throw new ConfigurationErrorsException("Timeout value is not in the configuration file."); } catch (Exception ex) { // Do nothing! }
Some developers believe you should also use:
try { .. } catch (Exception ex) { throw ex; }
How to catch exceptions
A better approach would be:/* Read the config file, and return the integer value. If it does not exist, then this is a problem! */ try { string value = ConfigurationManager.AppSettings["Timeout"]; if (value == null) throw new ConfigurationErrorsException("Timeout value is not in the configuration file."); } catch (Exception ex ) { throw; // <-- Throw the existing problem! }
Extra information within exceptions
An alternative is to give extra information (maybe local variable information) in addition to the exception. In this case, you wrap the exception within another. You usually use an exception that is as specific to the problem as possible, or create your own, if you cannot find out that is not specific enough (or if there is extra information you would wish to include).public OrderItem LoadItem(string itemNumber) { DataTable dt = null; try { if (itemNumber == null) throw new ArgumentNullException("Item Number cannot be null","itemNumber"); DataTable dt = DataAccess.OrderItem.Load(itemNumber); if (dt.Rows == 0) return null; else if (dt.Rows > 1) throw new DuplicateDataException( "Multiple items map to this item.",itemNumber, dt); OrderItem item = OrderItem.CreateInstanceFromDataRow(dt.Rows[0]); if (item == null) throw new ErrorLoadingException("Error loading Item " + itemNumber, itemNumber, dt.Rows[0]); } catch (DuplicateDataException dde) { throw new ErrorLoadingException("OrderItem.LoadItem failed with Item " + itemNumber, dde); // <-- Include dde (as the InnerException) parameter } catch (Exception ex) { throw; // <-- We aren't expecting any other problems, so throw them if they occur. } }
Thank you. I hope things are pretty clear here.
Comments
Post a Comment
Important - Make sure to click the Notify Me check-box below the comment to be notified of follow up comments and replies.