Exception handling

From Knowledge Kitchen
Jump to navigation Jump to search


Errors

Errors are Irrevocable problems that occur during program execution. Errors are fatal and cause the program to halt. These are usually caused by something external to the application code.

Running out of memory

If the computer an application is running on has no more memory left, this is usually a fatal error.

Stack overflow

If a program has a method that calls itself on an infinite loop, this will usually trigger a fatal error when the call stack exceeds its limits.

The following programs cause a stack overflow error to occur, because the function calls never stop piling up on the function call stack.

Java example

public static void method1() {
	System.out.println("starting method 1");
	method2();
	System.out.println("ending method 1");
}
public static void method2() {
	System.out.println("starting method 2");
	method1();
	System.out.println("ending method 2");
}

public static void main(String[] args) {
	System.out.println("starting main method");
	method1();
	System.out.println("ending main method");
}

Python example

def method1() :
	print("starting method 1")
	method2()
	print("ending method 1")

def method2() :
	print("starting method 2")
	method1()
	print("ending method 2")

def main() :
	print("starting main method")
	method1()
	print("ending main method")

main()

Exceptions

Exceptions are "irregularities" discovered while program is executing. Programs can be designed to recover from these exceptions and continue running. There are two conceptual types: checked and unchecked.

Checked exceptions

  • are anticipated
  • are declared in code as being known to possibly occur
  • exception handling code must be in place to handle their occurrence
  • are caused by unfortunate, but predictable problems such as invalid user input, database problems, network outages, absent files

Unchecked exceptions

  • are not anticipated
  • are left unhandled
  • cause catastrophic failure if they do occur and are not handled;
  • are almost always a result of errors in a program's logic

Handling exceptions

Most high-level programming languages have similar exception handling techniques.

The general pattern

The general pattern of exception handling is as follows:

In Java

try {
	//put some code here that might cause an exception
} 
catch (Exception e) {
	//optionally put some code here that should run if an exception occurs
	//it is possible to implement multiple catch blocks to catch exceptions of different kinds.
	//multiple catch blocks should go from more specific types of exceptions to more general.
} 
finally {
	//optionally put some code here that should run whether or not there was an exception.
	//the finally block often contain code that does some sort of clean-up to close any open resources
}

In Python

try :
	#put some code here that might cause an exception
except :
	#optionally put some code here that should run if an exception occurs
	#it is possible to implement multiple except blocks to catch exceptions of different kinds.
	#multiple except blocks should go from more specific types of exceptions to more general.
else :
	#optionally put some code here that should run if there was no exception
finally :
	#optionally put some code here that should run whether or not there was an exception.
	#the finally block often contain code that does some sort of clean-up to close any open resources

Typical example

The following examples show how to handle a typical 'file not found' exception, where the code tries to open a file that doers not exist.

Java example

try {
	//try opening a file
	System.out.println("Trying to open the file...");
	Scanner input = new Scanner(new File("src/data.txt"));
	System.out.println("Successfully opened the file...");
	//if there was no exception...
	//do something with the file and then close it
	input.close();
} 
catch (FileNotFoundException e) {
	//catch an exception indicating the file was not found
	System.out.println("Sorry, file not found..");
	System.out.println(e.toString());
} 
catch (Exception e) {
	//catch any other exception that may have occurred
	System.out.println("Sorry... some exception occurred.");
} 
finally {
	//regardless of whether there was an exception, do the following...
	System.out.println("Done!");
}

Python example

try :
	#try opening a file
	print("Trying to open the file...")
	input = open("src/data.txt")
	print("Successfully opened the file...")
except IOError as e :
	#catch an exception indicating the file was not found
	print("Sorry, file not found..")
	print(e)
except Exception as e :
	#catch any other exception that occurred
	print("Sorry... some exception occurred.")
	print(e)
else:
	#if there was no exception
	#do something with the file and then close it
	input.close()
finally :
	#regardless of whether there was an exception, do the following...
	print("Done!")

Throwing or raising exceptions

throws

When a particular method does not handle an exception that might happen within it, it can declare that it may throw that exception using the throws clause. This is a "polite" way of telling any methods that call this method that they should be prepared to handle this exception.

When a method is marked thus, any methods calling that method must either handle the type of exception that this method throws, or throw that exception themselves to other methods.

public void readFile() throws FileNotFoundException {
  //put code here that might cause a FileNotFoundException to be thrown
}

public static void main(String[] args) {
   try {
   	readFile(); 
   } catch (Exception e) {
   	//handle exception here
   }
}

throw

A method may catch an exception using try/catch and still decide to throw it to any method which called it. This can be achieved using the throw keyword.

public void readFile() throws FileNotFoundException{
	try {
		//put code here that might cause a FileNotFoundException to be thrown
	} catch (FileNotFoundException e) {
		System.out.println("oops");
		throw e; //pass the buck
	}
}

public static void main(String[] args) {
   try {
	 	readFile(); 
   } catch (Exception e) {
   	//handle exception here
   }
}

Custom exceptions

It's possible to create and throw your own custom Exceptions by extending the Exception class.

public void sipCoffee(CheapCupOfCoffee myCup) throws DisgustinglyColdException, InsanelyHotException {
        int temperature = myCup.getTemperature();
        if (temperature < minAcceptableTempForCoffee) {
            throw new DisgustinglyColdException();
        }
        else if (temperature > maxAcceptableTempForCoffee) {
            throw new InsanelyHotException();
        }
}
class DisgustinglyColdException extends Exception {
    public DisgustinglyColdException() {
        //any custom constructor setup
    }
}
class InsanelyHotException extends Exception {
    public InsanelyHotException() {
        //any custom constructor setup
    }
}


Java examples

File not found exception

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;


public class FileOpenException {
	/**
	 * override Object's default toString() method for our custom object
	 */
	public String toString() {
		return "This is a FileOpenException Object!";
	}
	
	public static void main(String[] args) {
		//create an object
		FileOpenException myObject = new FileOpenException();
		System.out.println(myObject.toString());

		
		try {
			System.out.println("Trying to open the file...");
			Scanner input = new Scanner(new File("src/data.txt"));
			System.out.println("Successfully opened the file...");
		} catch (FileNotFoundException e) {
			System.out.println("Sorry, file not found..");
			System.out.println(e.toString());
		} catch (Exception e) {
			System.out.println("Sorry... some exception occurred.");
		} finally {
			System.out.println("Cleaning up house...");
		}

	}

}


Throwing an exception

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;


public class ThrowsExceptionExample {

	public static void method1() throws Exception {
		System.out.println("method1 starting...");
		method2();
		System.out.println("method1 complete...");
	}
	
	public static void method2() throws Exception {
		System.out.println("method2 starting...");
		Scanner input = new Scanner(new File("src/data.txt"));
		System.out.println("method2 complete...");
	}
	
	public static void main(String[] args) {
		System.out.println("main method starting...");
		try {
			System.out.println("trying... ");
			method1();
		} catch (Exception e) {
			System.out.println("catching... ");
		}
		System.out.println("main method complete...");
	}

}


Custom exception

CustomException.java

public class CustomException extends Exception {
	public String toString() {
		return "Generated a custom exception.. hoorah!";
	}
}


TestCustomException.java

public class TestCustomException {

	public static void method1() throws CustomException {
		System.out.println("method1 starting...");
		throw new CustomException();
	}
	
	public static void main(String[] args) {
		System.out.println("main method starting...");
		try {
			System.out.println("calling method1");
			method1();			
			System.out.println("method1 returned control");
		} catch (Exception e) {
			System.out.println("Caught an exception");
			System.out.println(e.toString());
		}
		
		System.out.println("main method complete...");
	}

}


What links here