layer 1 layer 2 layer 3 layer 4 layer 5 abstract shapes

LotusScript Error Handling in a structured manner

Posted on December 14th 2016

A solution for more complex error handling in LotusScript.

Overview

As we all know, LotusScript has only basic error handling using the “On Error” mark-up. While this is ok for simple handling and ‘get the heck out of here’ code escapes, it’s not great for anything more complex.

Consider a more modern error handler:

	try {
		// do some code
	} catch (Exception e) {
		// handle the error
	} finally {
		// finish up
	}

Wouldn’t it be nice if we could do something similar? Well, albeit not quite there, consider this LotusScript:

	If True Then
try:
		On Error GoTo catch
		' do some code
	Else
catch:
		On Error GoTo 0
		' handle the error
		Resume finally
	End If
finally:

This may look a little odd at first, especially the first line but let’s draw some comparisons.

In the ‘modern’ example, the code within the try block will be executed and all being well, the code in the catch block will never be reached. In the end, the code in the finally block will always be executed.

In the LotusScript above the same is true. Because of the If True Then line, the code within that IF after the try: label will be executed and (since the result of the IF can never be False) the code within the ELSE after the catch: label will never be reached. In the end, anything outside the IF (after the finally: label) will always be executed.

This gets rid of the need to skip over our error handling using GoTo or having to use Exit Sub to get out before the execution gets there. For example, you’re probably more used to seeing these:

	On Error GoTo errHndlr
	' do some code
	GoTo endOfCode
errHndlr:
	' handle the error
	Resume endOfCode
endOfCode:

Or

	On Error GoTo errHndlr
	' do some code
	Exit Sub
errHndlr:
	' handle the error
	Resume endOfCode
endOfCode:

You can see that the new method is much neater and the error handling is immune to accidental execution.

Expanding on the method

The original example above would simply handle the error and then exit cleanly, but what if you wanted to throw the exception back up to the calling code? Rather nicely, LotusScript does support the bubbling of errors up to the caller, so consider this:

	If True Then
try:
		On Error GoTo catch
		' do some code
	Else
catch:
		On Error GoTo 0
		' bubble the error up to the caller
		Error Err, Error$
	End If
finally:

Notice we no longer have a Resume in the error handler and we simply throw the error back up to the caller. You can obviously send a different error up rather than just throw the error that actually happened:

catch:
		On Error GoTo 0
		' handle the error
		Error 9000, "Routine Failed"
	End If
finally:

Obviously, you can do all your usual error handling such as checking the error number and acting accordingly (as you would in more modern languages by having multiple catch expressions).

To take the examples further, here is a more fleshed out version:

Function exampleRoutine As String
	CONST fnName = "exampleRoutine (Sub)"
	Dim retVal As String

	If True Then
try:
		On Error GoTo catch
		' do some code
		retVal = "AOK"

	Else
catch:
		On Error GoTo 0
		MsgBox fnName & " ERROR: " & Error$ & " (" & Err & ") on line " & Erl

		' handle the error
		Select Case Err
		Case 4294:
			retVal = "EMAIL ERROR"
		Case Else
			' an error I can't handle here so pass back to caller
			Error Err, Error$
		End Select
		Resume finally
	End If

finally:
	exampleRoutine = retVal
End Function

Credit

Credit for this method goes to Cregg Hardwick based on his article on SearchDomino which can be read here. Adapted by Matthew Scott. This method builds on ideas Matthew had already put in place in his own code but improves on the layout. He has been using this method for some time in multiple projects and it has vastly improved the readability and maintainability of code.