Home

A Review of .NET Exception Classes

 

Introduction

The .NET Framework provides various classes to handle almost any type of exception you can think of. There are so many of these classes that we can only mention the few that we regularly use in our application.

There are two main ways you can use one of the classes of the .NET Framework. If you know for sure that a particular exception will be produced, pass its name to the catch() clause. You don't have to name the argument. Then, in the catch() section, display a custom message. The second option you have consists of using the throw keyword. We will study it later.

From now on, we will try to always indicate the type of exception that could be thrown if something goes wrong in a program

The FormatException Exception

When studying data formatting in Lesson 5, we saw that everything the user types into an application using the keyboard is primarily a string and that you must convert it to the appropriate type before using it. When you request a specific type of value from the user, after the user has typed it and you decide to convert it to the appropriate type, if your conversion fails, the program produces an error. The error is of the FormatException class.

Here is a program that deals with a FormatException exception:

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(FormatException)
        {
            Console.WriteLine("\nYou typed an invalid number");
        }

        return 0;
    }
}

Here is an example of running the program:

Square Processing
Enter Side: 25.9G

You typed an invalid number
Press any key to continue . . .

Practical LearningPractical Learning: Using the FormatException Class

  1. Change the OrderProcessing.cs file as follows (this includes the complete current version of the file):
     
    using System;
    
    namespace GeorgetownCleaningServices4
    {
        class 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();
    
                try
                {
                    Console.Write("Enter the order date(mm/dd/yyyy):  ");
                  cleaningOrder.OrderDate = DateTime.Parse(Console.ReadLine());
                }
                catch (FormatException)
                {
                Console.WriteLine("The value you entered is not a valid date");
                }
                try
                {
                    Console.Write("Enter the order time(hh:mm AM/PM): ");
                  cleaningOrder.OrderTime = DateTime.Parse(Console.ReadLine());
                }
                catch
                {
                Console.WriteLine("The value you entered is not a valid time");
                }
    
                // Request the quantity of each category of items
                try
                {
                    Console.Write("Number of Shirts:  ");
                  cleaningOrder.NumberOfShirts = uint.Parse(Console.ReadLine());
                    if (cleaningOrder.NumberOfShirts < uint.MinValue)
                        throw new OverflowException("Negative value not " +
    						"allowed for shirts");
                }
                catch (FormatException)
                {
                    Console.WriteLine("The value you typed for the number of " +
                            "shirts is not a valid number");
                }
                try
                {
                    Console.Write("Number of Pants:   ");
                    cleaningOrder.NumberOfPants = uint.Parse(Console.ReadLine());
                }
                catch(FormatException)
                {
                    Console.WriteLine("The value you typed for the number of " +
                                 "pair or pants is not a valid number");
                }
                try
                {
                    Console.Write("Number of Dresses: ");
                cleaningOrder.NumberOfDresses = uint.Parse(Console.ReadLine());
                }
                catch(FormatException)
                {
                    Console.WriteLine("The value you typed for the number of " +
                                 "dresses is not a valid number");
                }
                // 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
                try
                {
                    Console.Write("Amount Tended? ");
                    AmountTended = decimal.Parse(Console.ReadLine());
                }
                catch(FormatException)
                {
                    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()
            {
                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
        }
    }
  2. Execute the application and test it. Here is an example:
     
    -/- Georgetown Cleaning Services -/-
    Enter Customer Name:  Allen Dons
    Enter Customer Phone: 202-442-0400
    Enter the order date(mm/dd/yyyy):  7/14/2005
    Enter the order time(hh:mm AM/PM): 8:46 AM
    Number of Shirts:  5
    Number of Pants:   2
    Number of Dresses: 0
    
    The Total order is: $11.26
    Amount Tended? 15
    
    ====================================
    -/- Georgetown Cleaning Services -/-
    ====================================
    Customer:    Allen Dons
    Home Phone:  202-442-0400
    Order Date:  Thursday, July 14, 2005
    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      0   4.55        0.00
    ------------------------------------
    Total Order:   $10.65
    Tax Rate:      5.75 %
    Tax Amount:     $0.61
    Net Price:     $11.26
    ------------------------------------
    Amount Tended: $15.00
    Difference:     $3.74
    ====================================
    Press any key to continue . . .
  3. Close the DOS window

The OverflowException Exception

A computer application receives, processes, and produces values on a regular basis as the program is running. To better manage these values, as we saw when studying variables and data types in Lesson 1 and Lesson 2, the compiler uses appropriate amounts of space to store its values. It is not unusual that either you the programmer or a user of your application provides an value that is beyond the allowed range based on the data type. For example, we saw that a byte uses 8 bits to store a value and a combination of 8 bits can store a number no more than 255. If you provide a value higher than 255 to be stored in a byte, you get an error. Consider the following program:

using System;

// An Exercise class
class Exercise
{ 
    static int Main()
    {
	byte NumberOfPages;

	Console.Write("Enter the number of pages of the newspaper: ");
	NumberOfPages = byte.Parse(Console.ReadLine());

	Console.WriteLine("Number of Pages of the Newspaper: {0}\n", NumberOfPages);
    }

    return 0;
}

When a value beyond the allowable range is asked to be stored in memory, the compiler produces (the expression is "throws" as we will learn soon) an error of the OverflowException class. Here is an example of running the program:

Enter the number of pages of the newspaper: 824

Unhandled Exception: System.OverflowException: Value was either too large or too
 small for an unsigned byte.
   at System.Byte.Parse(String s, NumberStyles style, IFormatProvider provider)
   at System.Byte.Parse(String s)
   at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line
11

As with the other errors, when this exception is thrown, you should take an appropriate action.

The ArgumentOutOfRangeException Exception

Once again, when studying the techniques of converting or formatting values in Lesson 5, we saw that a value was passed to the Parse() method of its data type for analysis. For a primitive data type, the Parse() method scans the string and if the string cannot be converted into a valid value, the compiler usually produces a FormatException exception as we saw above. Other classes such as DateTime also use a Parse() method to scan the value submitted to it. For example, if you request a date value from the user, the DateTime.Parse() method scans the string to validate it. In US English, Parse() expects the user to type a string in the form m/d/yy or mm/dd/yy or mm/dd/yyyy. Consider the following program:

using System;

// An Exercise class
class Exercise
{ 
    static int Main()
    {
	DateTime DateHired;

	Console.Write("Enter Date Hired: ");
	DateHired = DateTime.Parse(Console.ReadLine());

	Console.WriteLine("Date Hired: {0:d}\n", DateHired);

	return 0;
    }
}

If the user types a value that cannot be converted into a valid date, the compiler produces an ArgumentOutOfRangeException exception. Here is an example of running the above program:

Enter Date Hired: 1244/04/258

Unhandled Exception: System.FormatException: String was not recognized as a valid DateTime.
   at System.DateTimeParse.Lex(Int32 dps, __DTString str, DateTimeToken dtok, 
DateTimeRawInfo raw, DateTimeResult result, DateTimeFormatInfo& dtfi)
   at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
   at System.DateTime.Parse(String s, IFormatProvider provider, DateTimeStyles styles)
   at System.DateTime.Parse(String s, IFormatProvider provider)
   at System.DateTime.Parse(String s)
   at Exercise.Main() in c:\programs\msvcs .net 2003\project17\exercise.cs:line 11

One way you can avoid this is to guide the user but still take appropriate actions.

The DivideByZeroException Exception

Division by zero is an operation to always avoid. It is so important that it is one of the most fundamental exceptions of the computer. It is addressed at the core level even by the Intel and AMD processors. It is also addressed by the operating systems at their level. It is also addressed by most, if not all, compilers. It is also addressed by most, if not all, libraries. This means that this exception is never welcomed anywhere. The .NET Framework also provides it own class to face this operation.

If an attempt to divide a value by 0 is performed, the compiler produces a DivideByZeroException exception.


Previous Copyright © 2006-2007 FunctionX, Inc. Next