Error Handling

By Asyrul Hafetzy

Agenda

  1. Understanding Error Handling
    • What and why
  2. Types of Error
    • Syntax Error
    • Runtime Error
    • Logical Error
  3. Tackling errors
    • Try, catch, finally
    • Throwing exceptions
  4. Quiz

What is an error?

When a code is run with mistakes that causes the software or program to misbehave

 

Thus producing and erroneous result

Types of Error

Compile-time

Runtime

Logical

Detected by the compiler

Example:

  • Syntax errors
  • Segmentation faults (in old languages like C)
  • Using an undeclared variable
  • Declaring variable twice
  • Scoping errors

Happens during runtime of program

Made possible by Exceptions

Example:

  • DivideByZeroException
  • IndexOutOfRangeException
  • NullPointerException

​Allows programmer to do Error Handling

Allows programmer to do Error Handling

Happens due to incorrect result of program

Requires programmer to study the code and/or flow of execution

Most difficult to debug

Example:

  • Incorrect mathematical formula

What is Error Handling?

The process of anticipating, detecting, and responding to anomalous or exceptional conditions, by implementing Exceptions

 

Usually requires the alteration of normal flow of program execution

 

Thus preventing software to crash

Understanding Exception

Exception is an anticipated or predicted problem that could occur when a program executes

 

Examples:

Division by zero

Input of incorrect format (eg. Phone number)

Input of incorrect value (eg. Negative value for age)

Exception Handling

Why?

 

  1. Enables developers to write fault-tolerant and robust programs
  2. Prevent user from inserting invalid values
  3. Prevent users from executing prohibited features
    • ​​Some features are only accessible for the admin
  4. Allow smooth user navigation  - prevent crashing

Tackling Errors

with Try and Catch

Try, Catch, Finally

Sample Code (C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ExceptionTutorial
{
    class TryCatchFinallyDemo
    {
        public static void Main(string[] args)
        {
 
            String text = "001234A2";
 
            int value = toInteger(text);
 
            Console.WriteLine("Value= " + value);
 
            Console.Read(); 
 
        }
 
        public static int toInteger(String text)
        {
            try
            {
 
                Console.WriteLine("Begin parse text: " + text);
 
                // An Exception can throw here (FormatException).
                int value = int.Parse(text);
 
                return value;
 
            }
            catch (FormatException e)
            {
                // In the case of 'text' is not a number.
                // This catch block will be executed.  
                Console.WriteLine("Number format exception: " + e.Message);
  
                return 0;
 
            }
            finally
            {
 
                Console.WriteLine("End parse text: " + text);
 
            }
 
        }
    }
 
}

Sample Code 2 (C#)

using System;
using System.IO;

class FinallyDemo
{
    static void Main(string[] args)
    {
        FileStream outStream = null;
        FileStream inStream = null;

        try
        {
            outStream = File.OpenWrite("DestinationFile.txt");
            inStream = File.OpenRead("BogusInputFile.txt");
        }
        catch(FileNotFoundException fnfex) //if file not found
        {
            Console.WriteLine(fnfex.ToString());
        }
        catch(PathTooLongException ptEx) //if file path too long
        {
            Console.WriteLine(ptEx.ToString());
        }
        catch(Exception ex) //other exceptions
        {
            Console.WriteLine(ex.ToString());
        }
        finally
        {
            if (outStream != null)
            {
                outStream.Close();
                Console.WriteLine("outStream closed.");
            }
            if (inStream != null)
            {
                inStream.Close();
                Console.WriteLine("inStream closed.");
            }
        }
    }
}

Tackling Errors

with Throwing

using System;

public class NumberGenerator
{
   int[] numbers = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
   
   public int GetNumber(int index)
   {
      if (index < 0 || index >= numbers.Length) {
         throw new IndexOutOfRangeException();

        //OR
        
        throw new Exception("Index value invalid!");
        // programmer's own customised exception
      }
      return numbers[index];
   }
}

public static void Main()
{
     var gen = new NumberGenerator();
     int index = 10;
     try 
    {
        int value = gen.GetNumber(index);
        Console.WriteLine($"Retrieved {value}");
    }
    catch (IndexOutOfRangeException e) 
    {
        Console.WriteLine($"{e.GetType().Name}: {index} is outside the bounds of the array");
    }
    catch(Exception e)
    {
        // displays a box to inform invalid input
        using(MessageBuilder Box = MessageBoxFactory.Create(e))
        {
            box.Show();
        }
    }
}

7 Best Practices in

Error Handling

1. Clean Up Resources in a Finally Block

2. Use specific Exceptions

3. Document / Comment the Exceptions You Specify

4. Throw Exceptions with Descriptive Messages

5. Catch the most specific exceptions first

6. Dont ignore exceptions

7. Dont Log and Throw

1. Clean Up Resources in a Finally Block

 

public void doNotCloseResourceInTry() {
	FileInputStream inputStream = null;
	try {
		File file = new File("./tmp.txt");
		inputStream = new FileInputStream(file);
		
		// use the inputStream to read a file
		
		// do NOT do this
		inputStream.close();
	} catch (FileNotFoundException e) {
		log.error(e);
	} catch (IOException e) {
		log.error(e);
	}
}
public void closeResourceInFinally() {
	FileInputStream inputStream = null;
	try {
		File file = new File("./tmp.txt");
		inputStream = new FileInputStream(file);
		
		// use the inputStream to read a file
		
	} catch (FileNotFoundException e) {
		log.error(e);
	} finally {
		if (inputStream != null) {
			try {
				inputStream.close();
			} catch (IOException e) {
				log.error(e);
			}
		}
	}
}

2. Prefer Specific Exceptions

 

public void doNotDoThis() throws Exception { ... }
	
public void doThis() throws NumberFormatException { ... }
  • Allow other developers to work with your code more easily
  • Maybe in a few months we might get back to make some changes to the code
  • As a result, caller of your method will be able to avoid it with an additional check

3. Document / Comment the Exceptions You Specify

/**
* This method does something extremely useful ...
*
* @param input
* @throws MyBusinessException if ... happens
*/
public void doSomething(String input) throws MyBusinessException { ... }

4. Throw exceptions with Descriptive Messages

try {
        // do something
	if(...)
        {
            Throw NumberFormatException("Your number format is wrong");
        }
} catch (NumberFormatException e) {
	log.error(e);
}
  • Describe as precisely as possible
  • provide relevant information to understand the exceptional event
  • Helps operations team to understand the problem
  • Should be grammatically correct

5. Catch specific Exceptions first

public void catchMostSpecificExceptionFirst() {
	try {
		doSomething("A message");
	} catch (NumberFormatException e) {
		log.error(e);
	} catch (IllegalArgumentException e) {
		log.error(e)
	}
}
  • Only the first catch block that matches the exception gets executed
  • If you catch IllegalArgumentException first, you will never reach something more specific, like NumberFormatException

6. Dont ignore exceptions

public void doNotIgnoreExceptions() {
	try {
		// do something
	} catch (NumberFormatException e) {
		// this will never happen
	}
}
  • Developer presumes that it would never be thrown and added an empty catch block that doesnt handle or logs the error
  • You should NEVER ignore an Exception
public void logAnException() {
	try {
		// do something
	} catch (NumberFormatException e) {
		log.error("This should never happen: " + e);
	}
}

7. Dont Log and Throw

try {
	new Long("xyz");
} catch (NumberFormatException e) {
	log.error(e);
	throw e;
}
  • Logging and exception when it occurs and then rethrow it so that the caller can handle it
  • Causes multiple error mesages of the same exception
  • If you need to add additional information, wrap the exception with a custom one
public void wrapException(String input) throws MyBusinessException {
	try {
		// do something
	} catch (NumberFormatException e) {
		throw new MyBusinessException("A message that describes the error.", e);
	}
}

QUIZ

References

  1. https://csharp-station.com/Tutorial/CSharp/Lesson15 

  2. https://www.guru99.com/java-exception-handling.html

  3. https://docs.microsoft.com/en-us/dotnet/csharp/language reference/keywords/throw

  4. https://o7planning.org/en/10445/csharp-exception-handling-tutorial

  5. https://stackify.com/best-practices-exceptions-java/

Thank You

Error Handling

By Asyrul Hafetzy

Error Handling

  • 178