Exception Handling


Introduction

Exception handling enables a programmer to cater for exceptional or problematic scenarios by defining a method of overriding the normal program flow during execution. When an exception occurs the normal program flow is interrupted and execution is directed to a piece of code in place to handle the exception which is called the catch statement.



How Exceptions Affect Program Flow

An exception is an event that interrupts the program flow of an application.

In the context of a Helium application when an exception occurs the active session will be failed and the transaction will be rolled back.

  • When an exception is thrown during a scheduled function an entry is written to the __scheduled_function_result__ table.
  • When an exception is thrown during a web users session an error is written to the Helium Logging Service and an "Exception encountered" error is displayed on the UI.

Execution happens from top to bottom of how the code reads, when an exception happens the transaction is failed, as mentioned above, the only case in which execute may continue is if the exception happens inside a try code block, this phenomenon is called exception handling.

To handle an exception the programmer can use the try statement with a catch block, when an exception is thrown from inside the try block execution is halted in the try and the statements inside the catch block are executed. A finally block can be used after a try-catch to ensure that execution of one more section of code in the scenario that an exception is thrown from the catch block, or there is a missing catch block.


Any type of event happens implicitly inside a transaction in Helium.

Using a Try Catch Block

The following code block shows the syntax of a try catch block, imagine that after the log in the try some sort of error happens, on execution we will see the following log entries: "inside try statement" then "inside catch statement" then "inside finally statement". When no exception is thrown the statements inside the catch block are not run. This shows the basic program flow.

try {
    Mez:log("inside try statement");
	// throws an exception now ...
} catch (ex){
    Mez:log("inside catch statement");
} finally {
    Mez:log("inside finally statement");
}

 Please note that, at present, exceptions resulting from SQLException cannot be handled by the try catch statement.


At present, exceptions resulting from SQLException cannot be handled by the try catch statement.

Handling the Exception

After the catch keyword to complete the statement there must be a variable name inside parentheses followed by a code block. On the exception that is caught there will always exist 6 values

  • message (string)
    • The message of the exception.
  • unitName (string)
    • The name of the DSL unit from which the exception was thrown.
  • unitLine (int)
    • The line number of the DSL unit from which the exception was thrown.
  • dateTimeStamp (datetime)
    • The date timestamp that the exception was thrown.
  • stackTrace (string)
    • The stack trace of the exception
  • toString (string)
    • A formatted string built using all the details of the exception (The template is: Exception at %s on line %d of unit %s. Message: %s. StackTrace: %s)

In the following example the try statement handles the exception by just logging it with Mez:log, in your application you will probably want do things like

  • Notify the user with a user friendly message with an Alert on the UI
  • Alter the program flow according to business rules
  • Notify via sms / email - in some cases.

// Example utility method to log the values found on an exception.
void logException(string message, string unitName, int unitLine, datetime dateTimeStamp, string stackTrace){
	string result = String:concat("Exception at ", "<<build your own message>>>");
	Mez:log(result);
}
 
void handleException(){
	try {
	    Mez:log("inside try statement");
		// throws an exception now ...
	} catch (ex){
	    Mez:log("inside catch statement");
		Mez:log(ex.toString);
		logException(ex.message, ex.unitName, ex.unitLine, ex.dateTimeStamp, ex.stackTrace);
	} finally {
	    Mez:log("inside finally statement");
	}
}




Using the Throw Statement

The programmer may throw an exception to interrupt the program flow and fail the transaction. This is done using the throw keyword, the throw keyword accepts a single value which will be converted to a string and used as the exception that is thrown within Helium.

void throwStatementExample(){
    Mez:log("Throwing an exception now ...");
    string error = "Oops, something went wrong!";
    throw error;
}




The Null Pointer Exception

Always remember that accessing a member on a null reference causes a null pointer exception, this like other exception can also be handled. Just take care not to swallow exceptions as it may lead to unexpected results.

void throwNPE(){
    person obj = null;
    obj.firstNames = "null pointer"; // Throws a NullPointerException
}



The programmers nemesis.

The Advantages of Using Exception Handling

  • Allows a separation between error handling code and regular code.
  • Allows a chance to recover from exceptions that the programmer can foresee.



The Disadvantages of Using Exception Handling

There are no real disadvantages of the proper use of exception handling, however take care not to swallow exceptions or the program may yield unexpected results.