CSIS 111B: Fundamentals of Computer Programming: Lessons

Lesson 12

Exception Handling

Objectives

By the end of this lesson you will be able to:

  • Understand what syntax errors are
  • Define what logic errors are
  • Define what exception errors are
  • Create a program which implements exception handling with try/catch
  • Create a program which implements exception handling with try/catch/finally
  • Understand what an API is
  • Understand what a library is
  • Understand what a framework is
  • Locate documentation for a particular framework or language

Understanding Exception Handling

There are at least three distinguishable types of errors in computer programming:

  • Syntax errors, also known as parsing errors are the most common errors you will encounter while learning a new programming language.
  • Logic errors, like when an algorithm returns a divide by zero error.
  • Exceptions, even if your statements and expressions are syntactically and logically correct, you program may still cause an error when it executes due to exceptions occurring, access to file resources is unavailable, network connection to resources is unavailable, etc. At this point your program will crash and become unusable - not an optimal experience for the users of your program. Fortunately by applying exception handling to the blocks of your code that are most susceptible to these errors, you can prevent your program from crashing when encountering one of these exceptions.

The .NET Framework supports standard exception handling to raise and handle runtime errors. In this section, you’ll learn how to use the try, catch, and finally keywords to handle exceptions.

An exception is an error condition that occurs during the execution of a computer program. When this happens, the runtime creates an object to represent the error and “throws” it. Unless you “catch” the exception by writing proper exception-handling code, program execution will terminate — a.k.a. crash.

For example, if you attempt to divide an integer by zero, a DivideByZeroException exception will be thrown. In the .NET Framework, an exception is represented by using an object of the System.Exception class or one of its derived classes. There are predefined exception classes that represent many commonly occurring error situations, such as the DivideByZeroException mentioned earlier. If you are designing an application that needs to throw any application-specific exceptions, you should create a custom exception class that derives from the System.Exception class.

Visual Studio Solution for Lesson 12

Table of Contents

Handling Exceptions With Try-Catch

To handle exceptions, place the code that throws the exceptions inside a try block and place the code that handles the exceptions inside a catch block.

The following example shows how to use a try-catch block to handle an exception. The exercise uses the File.OpenText method to open a disk file. This statement will execute just fine in the normal case, but if the file (or permission to read the file) is missing, then an exception will be thrown.

To create your own Visual Studio project which demonstrates this concept, do the following:

  1. Create a new Console Application project to the Lesson10 solution and name it HandlingExceptions.
  2. Right-click on the newly added HandlingExceptions project and choose Set as StatUp Project from the context menu that appears.
  3. Click anywhere in the Source code editor window and pres Ctrl + A on your keyboard to select all of the template code in your new project, and then press Delete.
  4. Type, or copy & paste, the following code into the Source code window for your HandlingExceptions project.
using System;
using System.IO;

namespace HandlingExceptions
{
    class Program
    {
        static void Main(string[] args)
        {
            ExceptionTest();
        }

        private static void ExceptionTest()
        {
            StreamReader sr = null;
            try
            {
                sr = File.OpenText(@"c:\data.txt");
                Console.WriteLine(sr.ReadToEnd());
            }
            catch (FileNotFoundException fnfe)
            {
                Console.WriteLine(fnfe.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}            
  1. Create a text file (“data.txt”) using Notepad or Visual Studio in the root of your computer's C: drive. It is acceptable to create the file at a different location, but if you do so, remember to modify the file location in the program. Type some text (anything you want) in the file and Save it.
  2. After you have added the text file to the root of your C: drive, press CTRL + F5 to run your HandlingExceptions project code without debugging. Your program should display the contents of the text file.
  3. Press a key to close the command window.
  4. Delete or rename the data.txt file and run the program again. This time, you’ll get a FileNotFoundException exception, and an appropriate message will be displayed in the output window.

To handle an exception, you enclose the statements that could cause the exception in a try block, then you add catch blocks to handle one or more exceptions. In this example, in addition to handling the more specific FileNotFoundException exception, we are also using a catch block with more generic exceptions to catch all other exceptions. The exception name for a catch block must be enclosed within parentheses. The statements that are executed when an exception is caught must be enclosed within curly braces.

Code execution stops when an exception occurs. The runtime searches for a catch statement that matches the type of exception. If the first catch block doesn’t catch the raised exception, control moves to the next catch block, and so on. If the exception is not handled in the method, the runtime checks for the catch statement in the calling code and continues for the rest of the call stack.

Note: In the ExceptionTest method, it is incorrect to change the order of the two catch blocks. The more specific exceptions need to be listed before the generic exceptions, or else you’ll get compilation errors. Another way of saying that is, always order exceptions from the most derived to the least derived

Note: This is not your first time seeing the @ symbol used in a C# statement. You were introduced to the "verbatim identifier" back in Lesson 5. When placed in front of a string like the one in our example, "c:/data.txt", the @ symbol indicates to the compiler to treat the string literally (exactly as written). This can be useful when a backslash character is typed inside of a string value. Normally the compiler sees the backslash character in a string as what is known as an escape character. In C# coding, escape characters are used to change the normal behavior of the compiler in order to handle characters in a string that would normally cause a compiler error. For example, say you wanted to have literal quotes in a string value, you can't type "this is a quote " symbol" because the compiler would think that the string value should end after the word quote instead of where it should end after the word symbol. To fix this problem you can use an escape sequence like this "this is a quote \" symbol". In this example the backslash character is telling the compiler to treat the " character after the word quote as a character that is part of the string value and not the end of the string value. Escape characters are commonly used for this purpose in most programming languages. However, the question arises as to how then do we convey to a compiler that we want it to include a backslash character in a string and not treat it as an escape sequence? The answer is we use two backslashes. Telling the compiler that the first backslash begins the escape sequence and the second backslash is the literal character we want to include in the string value. Using our example above, you would normally write the file path string using the backslash escape sequence like this: "c:\\data.txt", to avoid this we can use the @ symbol instead. By putting the @ symbol before the string value we are telling the compiler to ignore any and all escape characters that it finds inside of our string value.

If you are interested in learning more about escape sequences used in C# coding view the table in this Character literals tutorial.

Table of Contents

Handling Divide By Zero Errors

As shown in the example above Exception Handling can be used to avoid IO errors like accessing files on a local hard disk drive or even a network located resource. In fact, exception handling can be used to avoid many possible situations where you the programmer would have no control, take user input for example. Many time users ignore or don't bother to read your on-screen instructions for how to input data into your program correctly. Here again exception handling comes in handy.

In our next example we'll look at handling a common mathematical calculation error know as divide by zero.

Create your own Visual Studio project which demonstrates this concept, by doing the following:

  1. Open your Lesson10 solution in Visual Studio
  2. Add a new Console Application project to the Lesson1 solution and name it ArithmeticException.
  3. Right-click on the newly added HandlingExceptions project and choose Set as StatUp Project from the context menu that appears.
  4. Click anywhere in the Source code editor window and pres Ctrl + A on your keyboard to select all of the template code in your new project, and then press Delete.
  5. Type the following code into the Source code window for your ArithmeticException project.
using System;

namespace ExceptionHandling
{
    class Program
    {
        public static void Main()
        {
            int x = 10;
            int y = 0;
            Console.WriteLine(Divide(x, y));
        }

        public static int Divide(int x, int y)
        {
            int results = 0;
            try
            {
                results = x / y;
            }
            catch (ArithmeticException e)
            {
                Console.WriteLine(
                    "ArithmeticException Handler: {0}",
                    e.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine(
                    "Generic Exception Handler: {0}",
                    e.ToString());
            }
            return results;
        }
    }
}            
  1. Press CTRL + F5 to run your ArithmeticException project code without debugging. Your program should display an arithmetic exception error.

Note: A try block must have at least a catch block or a finally block associated with it.

Table of Contents

Using Try-Catch-Finally

The finally block is used in association with the try block. The finally block is always executed regardless of whether an exception is thrown. The finally block is often used to write clean-up code.

Note: Microsoft documentation recommends that developer's prefer using statements to automatically clean up resources when exceptions are thrown. Use finally blocks to clean up resources that don't implement IDisposable. Code in a finally clause is almost always executed even when exceptions are thrown.

When an exception occurs, it often means that some lines of code after the exception were not executed. This may leave your program in a dirty or unstable state. To prevent such situations, you can use the finally statement to guarantee that certain cleanup code is always executed. This may involve closing connections, releasing resources, or setting variables to their expected values. We'll look at the finally block in the following exercise.

Create your own Visual Studio project which demonstrates this concept, by doing the following:

  1. Open your Lesson10 solution in Visual Studio
  2. Add a new Console Application project to the Lesson10 solution and name it TryCatchFinally.
  3. Right-click on the newly added TryCatchFinally project and choose Set as StatUp Project from the context menu that appears.
  4. Click anywhere in the Source code editor window and pres Ctrl + A on your keyboard to select all of the template code in your new project, and then press Delete.
  5. Type, or copy & paste, the following code into the Source code window for your TryCatchFinally project.
using System;
using System.IO;

namespace TryCatchFinally
{
    class Program
    {
        static void Main(string[] args)
        {
            TryCatchFinallyTest();
        }

        private static void TryCatchFinallyTest()
        {
            StreamReader sr = null;
            try
            {
                sr = File.OpenText("data.txt");
                Console.WriteLine(sr.ReadToEnd());
            }
            catch (FileNotFoundException fnfe)
            {
                Console.WriteLine(fnfe.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (sr != null)
                {
                    sr.Close();
                }
            }
        }
    }
}  
  1. Press CTRL + F5 to run your TryCatchFinally project code without debugging.

In this example, the program makes sure that the StreamReader object is closed and any resources are released when the operation completes. The code in the finally block is executed regardless of whether an exception is thrown.

Adding Exception Handling to Modular Programs

This next bit of code applies what you learned here about exception handling with the modular structure you learned in the Modular Programming lesson.

using System;

// In order to use StreamWriter and StremReader classes
//System.IO library is needed
using System.IO;

namespace ExceptionHandling
{
    class Program
    {
        static void Main()
        {
            // Prompt user for text input
            Console.WriteLine("Enter text to save:");

            // Assign text input to variable textInput
            string textInput = Console.ReadLine();

            try
            {
                // Call WriteFile method and pass 'textInput' as an
                // argument. Catching any file exception errors
                WriteFile(textInput);

                // Read the contents of MyText.txt file
                // Catching any file exception errors
                ReadFile();
            }

            // Catch file exception errors
            catch (FileNotFoundException fnfe)
            {
                Console.WriteLine(fnfe.Message);
            }

            // Catch errors of unknown type
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private static void WriteFile(string textInput)
        {
            // Create and use an instance of a StreamWriter
            // class with file name 'MyText.txt'
            using StreamWriter writer = new StreamWriter("MyText.txt");
            {
                // Write 'textInput' stream to the MyText.txt file
                writer.WriteLine(textInput);
            }
        }
        private static void ReadFile()
        {
            // Create and use an instance of a StreamReader
            //class to read 'MyText.txt'
            using StreamReader sr = new StreamReader("MyText.txt");
            {
                // Declare a string variable 'line'
                //to hold contents of stream
                string line;

                // Label screen output
                Console.WriteLine("The content of MyText.txt:");

                // Read and display lines from the file until the end of 
                // The file is reached.
                while ((line = sr.ReadLine()) != null)
                {
                    // Display each line of text
                    //from 'sr' StreamReader object
                    Console.WriteLine(line);
                }
            }

        }
    }
}

This way of organizing your source code works well if we are only dealing with file IO errors. If we also wanted to call a function from our Main() method which could cause a divide by zero error our current code would not handle that specific exception, however, the program would still not crash because of the use of the generic Exception handler. We just wouldn't get the specific error type reported from within the program.

Table of Contents

Application Programming Interfaces (APIs)

An API can be defined as "a set of clearly defined methods of communication between various software components." The best way to think of an API is as a building block that can be used to add functionality to your program. Any professionally written API that you use will have a well defined interface with some kind documentation on how to use it. APIs come in all shapes and formats and depending on the type of programming you are building you might even use an API written in a different programming language than the program you are writing in, however you won't care because all you need to know is how to interact with the API using its provided interface.

Images representig the Google, Twitter, and Facebook APIs, Web pages, and mobile apps.
Table of Contents

Amazon Web Services

screenshot of the AWS homepage.
Table of Contents

Facebook for Developers

Image of the facebook for developers toolbar.
Image showing a sample facebook developer's dashboard screen.
Table of Contents

Google Developers

Website

Google Developers
screen capture from google developer's home page.
Table of Contents

Libraries

Libraries come in many different configurations, but generally they are a collection of functions, APIs, Classes, or pre-compiled objects that can be used to provide added functionality to an application without you having to write the code required to accomplish the same task. Libraries are also contained within Frameworks, as you can see in the Frameworks section on this page.

JavaScript Libraries

There are currently numerous JavaScript libraries available for use in enhancing your Web site or application.

jQuery is one of the more popular and well known JavaScript libraries.

React is a JavaScript library developed by Facebook for creating modular user interfaces.

Table of Contents

Frameworks

The best way to think of a software framework is as a comprehensive system for developing applications by utilizing an existing code base provided by an included coding library. Depending on the framework, it may or may not be open-source, it could have supporting tools like a compiler, or a code editor enhanced for the programming language used. The biggest drawback to using a particular framework could be that you can only code for certain platforms, or a change to the existing code library may change and break your program.

Here is a recent article written about software frameworks; the author lists seven reasons why frameworks are the new programming languages.

Javascript Frameworks

Angular is a JavaScript framework developed by Google.

TypeScript is a typed superset of JavaScript that complies to plain JavaScript.

Web Assembly is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the Web for client and server applications. Developer reference documentation.

The .Net Framework

The .NET (pronounced dot net) framework is a software framework developed by Microsoft that, until recently, ran primarily on computers running the Microsoft Windows operating system. However, Microsoft has made most of its coding libraries available as "open-source" allowing a larger community of developers to contribute to its content, but also with the advent of .NET Core, has now made it so that programs written using the .NET framework can now run on any device running either the Android, OS X, iOS, or Linux operating systems in addition to Windows.

The .NET framework includes a large class library named the Framework Class Library (FCL) and provides language interoperability (each language can use code written in other languages) across several programming languages. Programs written for .NET framework execute in a software environment (in contrast to a hardware environment) named Common Language Runtime (CLR), an application virtual machine that provides services such as security, memory management, and exception handling. (As such, computer code written using .NET framework is called "managed code".) FCL and CLR together constitute the .NET Framework.

The layered architecture of the .NET framework.
Table of Contents

Finding Documentation

C# and Microsoft .NET

In order to learn about the classes that are available in the .NET library, including their properties, methods, and events, check out Microsoft Documents Website by navigating your Web browser to https://docs.microsoft.com/en-us/dotnet/, this is where we'll find the home page for the .NET Documentation.

.NET Documentation screen

On this page we see a menu of topics on the left and links to documentation for the three, standard, core, and framework .NET libraries on the right.

JavaScript

The Mozilla Developer's Network (MDN) is an excellent resource for documentation on the core JavaScript language. For documentation on JavaScript libraries or frameworks like jQuery or React, you need to go to the Website for the specific library or framework you need the documentation for.

C++

The Website cplusplus.com is a good resource for the C++ language.

Python

For information about the python language docs.python.org is a good resource.

Table of Contents

How To Become and What It's Like To Be A Programmer

The following is a series of videos by a gentleman of the name of John Sonmez. I am not endorsing him nor his products here, I just found these videos interesting, provocative, and entertaining and thought you might enjoy viewing them as well.

What Was Your First Programming Job Like?

Table of Contents

What Do You Need To Know For Your First Developer Job?

Table of Contents

Programming Job With No Experience

Table of Contents

How To Become A Software Developer Without A Degree

Table of Contents

Summary

In this lesson you learned what syntax errors are, what logic errors are, what exception errors are, how to create a program which implements exception handling with try/catch, finally blocks, how to handle specific exception types, how to implement a verbatim identifier to simplify path statements, what an API is, what a library is, what a framework is, how to find documentation for libraries, frameworks, and programming languages and how to go about finding and keeping a programming job.