Home

Introduction to Exception Handling

 

Overview

During the execution of a program, the computer will face two types of situations: those it is prepared to deal with and those it is not. Imagine you write a program that requests a number from the user:

using System;

class Program
{
    static int Main()
    {
        double side;

        Console.WriteLine("Square Processing");
        Console.Write("Enter Side: ");
        side = double.Parse(Console.ReadLine());

        Console.WriteLine("\nSquare Characteristics");
        Console.WriteLine("Side:      {0}", side);
        Console.WriteLine("Perimeter: {0}", side * 4);
        return 0;
    }
}

This is a classic easy program. When it comes up, the user is asked to simply type a number. The number would then be multiplied by 4 and display the result. Imagine that a user types something that is not a valid number, such as the name of a country or somebody’s telephone number. Since this program was expecting a number and it is not prepared to multiply a string to a number, it would not know what to do. The only alternative the compiler would have is to send the problem to the operating system, hoping that the OS would know what to do. What actually happens is that, whenever the compiler is handed a task, it would try to perform the assignment. If it can’t perform the assignment, for any reason it is not prepared for, it would produce an error. As a programmer, if you can anticipate the type of error that could occur in your program, you can identify the error yourself and deal with it by telling the compiler what to do when this type of error occurs.

 

Practical LearningPractical Learning: Introducing Exception Handling

  1. Start Microsoft Visual C# and create a Console Application named GeorgetownCleaningServices4
  2. To create a new class, in the Solution Explorer, right-click GeorgetownCleaningServices2 -> Add -> Class...
  3. Set the Name to CleaningOrderInfo and click OK
  4. Change the file as follows:
     
    using System;
    
    namespace GeorgetownCleaningServices4
    {
        public class CleaningOrderInfo
        {
            // Basic information about an order
            public string CustomerName;
            public string HomePhone;
            public DateTime OrderDate;
            public DateTime OrderTime;
            // Unsigned numbers to represent cleaning items
            public uint NumberOfShirts;
            public uint NumberOfPants;
            public uint NumberOfDresses;
        }
    }
  5. To create a new class, on the main menu, click Project -> Add Class...
  6. Set the Name to OrderProcessing and press Enter
  7. Change the file as follows:
     
    using System;
    
    namespace GeorgetownCleaningServices4
    {
        public class sealed OrderProcessing
        {
            #region Objects used to process an order
            // Price of items
            const decimal PriceOneShirt = 0.95M;
            const decimal PriceAPairOfPants = 2.95M;
            const decimal PriceOneDress = 4.55M;
            const decimal TaxRate = 0.0575M;  // 5.75%
    
            CleaningOrderInfo cleaningOrder;
    
            // Each of these sub totals will be used for cleaning items
            private decimal SubTotalShirts;
            private decimal SubTotalPants;
            private decimal SubTotalDresses;
    
            // Values used to process an order
            private decimal TotalOrder;
            private decimal TaxAmount;
            private decimal SalesTotal;
            private decimal AmountTended;
            private decimal Difference;
    
            #endregion
    
            #region Actions used to process and present an order
    
            public OrderProcessing()
            {
                cleaningOrder = new CleaningOrderInfo();
            }
    
            public void ProcessOrder()
            {
                Console.WriteLine("-/- Georgetown Cleaning Services -/-");
                // Request order information from the user
                Console.Write("Enter Customer Name:  ");
                cleaningOrder.CustomerName = Console.ReadLine();
                Console.Write("Enter Customer Phone: ");
                cleaningOrder.HomePhone = Console.ReadLine();
                Console.Write("Enter the order date(mm/dd/yyyy):  ");
                cleaningOrder.OrderDate = DateTime.Parse(Console.ReadLine());
                Console.Write("Enter the order time(hh:mm AM/PM): ");
                cleaningOrder.OrderTime = DateTime.Parse(Console.ReadLine());
    
                // Request the quantity of each category of items
                Console.Write("Number of Shirts:  ");
                cleaningOrder.NumberOfShirts = uint.Parse(Console.ReadLine());
    
                Console.Write("Number of Pants:   ");
                cleaningOrder.NumberOfPants = uint.Parse(Console.ReadLine());
    
                Console.Write("Number of Dresses: ");
                cleaningOrder.NumberOfDresses = uint.Parse(Console.ReadLine());
    
                // Perform the necessary calculations
                SubTotalShirts = cleaningOrder.NumberOfShirts * PriceOneShirt;
                SubTotalPants = cleaningOrder.NumberOfPants * PriceAPairOfPants;
                SubTotalDresses = cleaningOrder.NumberOfDresses * PriceOneDress;
                // Calculate the "temporary" total of the order
                TotalOrder = SubTotalShirts + SubTotalPants + SubTotalDresses;
    
                // Calculate the tax amount using a constant rate
                TaxAmount = TotalOrder * TaxRate;
                // Add the tax amount to the total order
                SalesTotal = TotalOrder + TaxAmount;
    
                // Communicate the total to the user...
                Console.WriteLine("\nThe Total order is: {0:C}", SalesTotal);
                // and request money for the order
                Console.Write("Amount Tended? ");
                AmountTended = decimal.Parse(Console.ReadLine());
    
                // Calculate the difference owed to the customer
                // or that the customer still owes to the store
                Difference = AmountTended - SalesTotal;
    
                ShowReceipt();
            }
    
            private void ShowReceipt()
            {
                Console.WriteLine();
                // Display the receipt
                Console.WriteLine("====================================");
                Console.WriteLine("-/- Georgetown Cleaning Services -/-");
                Console.WriteLine("====================================");
                Console.WriteLine("Customer:    {0}", cleaningOrder.CustomerName);
                Console.WriteLine("Home Phone:  {0}", cleaningOrder.HomePhone);
                Console.WriteLine("Order Date:  {0:D}", cleaningOrder.OrderDate);
                Console.WriteLine("Order Time:  {0:t}", cleaningOrder.OrderTime);
                Console.WriteLine("------------------------------------");
                Console.WriteLine("Item Type  Qty Unit/Price Sub-Total");
                Console.WriteLine("------------------------------------");
                Console.WriteLine("Shirts     {0,3}   {1,4}      {2,6}",
                    cleaningOrder.NumberOfShirts, PriceOneShirt, SubTotalShirts);
                Console.WriteLine("Pants      {0,3}   {1,4}      {2,6}",
                    cleaningOrder.NumberOfPants, PriceAPairOfPants, SubTotalPants);
                Console.WriteLine("Dresses    {0,3}   {1,4}      {2,6}",
                    cleaningOrder.NumberOfDresses, PriceOneDress, SubTotalDresses);
                Console.WriteLine("------------------------------------");
                Console.WriteLine("Total Order:   {0,6}", TotalOrder.ToString("C"));
                Console.WriteLine("Tax Rate:      {0,6}", TaxRate.ToString("P"));
                Console.WriteLine("Tax Amount:    {0,6}", TaxAmount.ToString("C"));
                Console.WriteLine("Net Price:     {0,6}", SalesTotal.ToString("C"));
                Console.WriteLine("------------------------------------");
                Console.WriteLine("Amount Tended: {0,6}", AmountTended.ToString("C"));
                Console.WriteLine("Difference:    {0,6}", Difference.ToString("C"));
                Console.WriteLine("====================================");
            }
            #endregion
        }
    }
  8. Access the program.cs file and change it as follows:
     
    using System;
    
    namespace GeorgetownCleaningServices4
    {
        class Program
        {
            static int Main()
            {
                OrderProcessing Order = new OrderProcessing();
    
                Order.ProcessOrder();
                return 0;
            }
        }
    }
  9. Execute the application and test it. Here is an example:
     
    -/- Georgetown Cleaning Services -/-
    Enter Customer Name:  Peter Moonstruck
    Enter Customer Phone: (301) 728-8830
    Enter the order date(mm/dd/yyyy):  04/22/2006
    Enter the order time(hh:mm AM/PM): 08:46
    Number of Shirts:  5
    Number of Pants:   2
    Number of Dresses: 3
    
    The Total order is: $25.70
    Amount Tended? 30
    
    ====================================
    -/- Georgetown Cleaning Services -/-
    ====================================
    Customer:    Peter Moonstruck
    Home Phone:  (301) 728-8830
    Order Date:  Saturday, April 22, 2006
    Order Time:  8:46 AM
    ------------------------------------
    Item Type  Qty Unit/Price Sub-Total
    ------------------------------------
    Shirts       5   0.95        4.75
    Pants        2   2.95        5.90
    Dresses      3   4.55       13.65
    ------------------------------------
    Total Order:   $24.30
    Tax Rate:      5.75 %
    Tax Amount:     $1.40
    Net Price:     $25.70
    ------------------------------------
    Amount Tended: $30.00
    Difference:     $4.30
    ====================================
    Press any key to continue . . .
  10. Close the DOS window

Exceptional Behaviors

An exception is an unusual situation that could occur in your program. As a programmer, you should anticipate any abnormal behavior that could be caused by the user entering wrong information that could otherwise lead to unpredictable results. The ability to deal with a program’s eventual abnormal behavior is called exception handling. C# provides three keywords to handle an exception.

  1. Trying the normal flow: To deal with the expected behavior of a program, use the try keyword as in the following syntax:

    try {Behavior}

    The try keyword is required. It lets the compiler know that you are attempting a normal flow of the program. The actual behavior that needs to be evaluated is included between an opening curly bracket “{“ and a closing curly bracket “}”. Inside of the brackets, implement the normal flow that the program must follow, at least for this section of the code. Here is an example:
     
    using System;
    
    class Program
    {
        static int Main()
        {
            double side;
    
            Console.WriteLine("Square Processing");
    
            try
            {
                Console.Write("Enter Side: ");
                side = double.Parse(Console.ReadLine());
    
                Console.WriteLine("\nSquare Characteristics");
                Console.WriteLine("Side:      {0}", side);
                Console.WriteLine("Perimeter: {0}", side * 4);
            }
    
            return 0;
        }
    }
  2. Catching Errors: During the flow of the program as part of the try section, if an abnormal behavior occurs, instead of letting the program crash or instead of letting the compiler send the error to the operating system, you can transfer the flow of the program to another section that can deal with it. The syntax used by this section is:

    catch {WhatToDo}

    This section always follows the try section. There must not be any code between the try’s closing bracket and the catch section. The catch keyword is required and follows the try section. Combined with the try block, the syntax of an exception would be:
     
    try
    {
        // Try the program flow
    }
    catch
    {
        // Catch the exception
    }

    A program that includes a catch section would appear as follows:
     
    using System;
    
    public class Exercise
    {
        static int Main()
        {
    	double Number;
    
    	try 
    	{
    	    Console.Write("Type a number: ");
    	    Number = double.Parse(Console.ReadLine());
    
    	    Console.WriteLine("\n{0} * 2 = {1}", Number, Number * 2);
    	}
    	catch
    	{
    	}
    
            return 0;
        }
    }

 

Practical LearningPractical Learning: Introducing Vague Exceptions

  1. To introduce exceptions, access the OrderProcessing.cs file and change it as follows:
     
    using System;
    
    namespace GeorgetownCleaningServices4
    {
        class OrderProcessing
        {
    	. . . No Change
    
    	public void ProcessOrder() 
    	{
    		. . . No Change
    
    	    // Request the quantity of each category of items
    	    try 
    	    {
    		Console.Write("Number of Shirts:  ");
    		Order.NumberOfShirts = uint.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    	    }
    			
    	    try 
    	    {
    		Console.Write("Number of Pants:   ");
    		Order.NumberOfPants = uint.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    	    }
    			
    	    try 
    	    {
    		Console.Write("Number of Dresses: ");
    		Order.NumberOfDresses = uint.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    	    }
    			
    	    . . . No Change
    
    	    // and request money for the order
    	    try 
    	    {
    		Console.Write("Amount Tended? ");
    		AmountTended    = decimal.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    	    }
    
    	    // Calculate the difference owed to the customer
    	    // or that the customer still owes to the store
    	    Difference      = AmountTended - SalesTotal;
    
    	    ShowReceipt();
    	}
    
    	private void ShowReceipt()
    	{
    		. . . No Change
    	}
        }
    }
  2. Execute the application to test it
  3. Close the DOS window
 

Exceptions and Custom Messages

As mentioned already, if an error occurs when processing the program in the try section, the compiler transfers the processing to the next catch section. You can then use the catch section to deal with the error. At a minimum, you can display a message to inform the user. Here is an example:

using System;

class Program
{
    static int Main()
    {
        double side;

        Console.WriteLine("Square Processing");
        try
        {
            Console.Write("Enter Side: ");
            side = double.Parse(Console.ReadLine());

            Console.WriteLine("\nSquare Characteristics");
            Console.WriteLine("Side:      {0}", side);
            Console.WriteLine("Perimeter: {0}", side * 4);
        }
        catch
        {
            Console.WriteLine("There was a problem with the program");
        }

        return 0;
    }
}

Here is an error of running the program:

Square Processing
Enter Side: w4
There was a problem with the program
Press any key to continue . . .

Of course, this type of message is not particularly clear but this time, the program will not crash. In the next sections, we will learn better ways of dealing with the errors and the messages.

 

Practical LearningPractical Learning: Displaying Custom Messages

  1. To display custom messages to the user, change the OrderProcessing.cs file as follows:
     
    using System;
    
    namespace GeorgetownCleaningServices4
    {
        class OrderProcessing
        {
    		. . . No Change
    
    	public void ProcessOrder() 
    	{
    		. . . No Change
    
    	    // Request the quantity of each category of items
    	    try 
    	    {
    		Console.Write("Number of Shirts:  ");
    		Order.NumberOfShirts = uint.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    		Console.WriteLine("The value you typed for the number of " +
    				  "shirts is not a valid number");
    	    }
    			
    	    try 
    	    {
    		Console.Write("Number of Pants:   ");
    		Order.NumberOfPants = uint.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    		Console.WriteLine("The value you typed for the number of " +
    		  	          "pair or pants is not a valid number");
    	    }
    			
    	    try 
    	    {
    		Console.Write("Number of Dresses: ");
    		Order.NumberOfDresses = uint.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    		Console.WriteLine("The value you typed for the number of " +
    			          "dresses is not a valid number");
    	    }
    			
    	    . . . No Change
    
    	    try 
    	    {
    		Console.Write("Amount Tended? ");
    		AmountTended    = decimal.Parse(Console.ReadLine());
    	    }
    	    catch
    	    {
    		Console.WriteLine("You were asked to enter an amount of money but...");
    	    }
    
    	    // Calculate the difference owed to the customer
    	    // or that the customer still owes to the store
    	    Difference      = AmountTended - SalesTotal;
    
    	    ShowReceipt();
    	}
    
    	private void ShowReceipt()
    	{
    		. . . No Change
    	}
        }
    }
  2. Execute the application to test it. Here is an example:
     
    -/- Georgetown Cleaning Services -/-
    Enter Customer Name:  Alexandria
    Enter Customer Phone: (102) 797-8382
    Enter the order date(mm/dd/yyyy):  04/02/2001
    Enter the order time(hh:mm AM/PM): 09:22 AM
    Number of Shirts:  6
    Number of Pants:   W
    The value you typed for the number of pair or pants is not a valid number
    Number of Dresses: 5
    
    The Total order is: $30.09
    Amount Tended? _100D
    You were asked to enter an amount of money but...
    
    ====================================
    -/- Georgetown Cleaning Services -/-
    ====================================
    Customer:    Alexandria
    Home Phone:  (102) 797-8382
    Order Date:  Monday, April 02, 2001
    Order Time:  9:22 AM
    ------------------------------------
    Item Type  Qty Unit/Price Sub-Total
    ------------------------------------
    Shirts       6   0.95        5.70
    Pants        0   2.95           0
    Dresses      5   4.55       22.75
    ------------------------------------
    Total Order:   $28.45
    Tax Rate:      5.75 %
    Tax Amount:     $1.64
    Net Price:     $30.09
    ------------------------------------
    Amount Tended:  $0.00
    Difference:    ($30.09)
    ====================================
  3. Close the DOS window
 

Home Copyright © 2006 FunctionX, Inc. Next