Error Handling
Sometimes the code throws a runtime exception (e.g. unexpected null value, invalid number format, …). Such exceptions can be handled using one of the following approaches:
- Try-Catch Statement - recommended
- OnError() Functions
Try-Catch Statement
You may use the try-catch
statement to handle runtime errors.
For every try
statement, there can be only one catch
block as there is only one type of exception: CTLException
. Additionally, there is no finally
block. In CTL, there are two parts to try-catch
statement:
try
block allows you to define a code to be tested for errorscatch
block’s purpose is to handle errors that might occur within thetry
block
Depending on whether the try block encounters an error or not, the execution of the statement may lead to two alternatives:
- If the
try
block executes without errors, the followingcatch
block is skipped, and the wholetry-catch
statement completes successfully. - If the code inside the
try
block is erroneous, the execution jumps to the beginning of the respectivecatch
block and executes the code within it.
The implementation of how to handle the error is up to you. For example, you can throw a custom error using the raiseError()
function, log the exception and have the execution finish successfully, or execute a custom code as a workaround for the exception. You can access some details about the exceptions via the CTLException
data structure.
try-catch
statements can be nested.
Example 75. Try-Catch Statement
integer a = 123;
integer b = 0;
integer c;
try {
c = a / b; // throws ArithmeticException
printLog(info, c); // skipped
} catch (CTLException ex) {
c = -1; // workaround: set the variable to -1 to indicate error
printLog(warn, ex); // log a warning
}
CTLException
is actually a data record with the following fields:
sourceRow: integer
the row of the CTL source code where the exception occurred
sourceColumn: integer
the column of the CTL source code where the exception occurred
message: string
the error message of the innermost exception - the original cause of the failure
cause: string
the type of the innermost exception, e.g. java.lang.ArithmeticException
stackTrace: list[string]
the cascade of function calls that caused the failure
exceptionTrace: list[string]
the list of exception types from the outermost to the innermost
OnError() Functions
Alternatively to the Try-Catch Statement, you can use a set of optional OnError()
functions that exist to each required transformation function.
For example, for required functions (e.g. append(), transform()
, etc.), there exist following optional functions:
appendOnError(), transformOnError()
, etc.
Each of these required functions may have its (optional) counterpart whose name differs from the original (required) by adding the OnError
suffix.
Moreover, every <required ctl template function>OnError()
function returns the same values as the original required function.
This way, any exception that is thrown by the original required function causes call of its <required ctl template function>OnError()
counterpart (e.g. transform()
fail may call transformOnError()
, etc.).
In this transformOnError()
, any incorrect code can be fixed, an error message can be printed to the Console, etc.
Remember that theseOnError()
functions are not called when the original required functions return **Error codes** (values less then -1).
If you want someOnError()
function to be called, you need to use theraiseError(string arg)
function. Or (as stated before) any exception thrown by original required function calls itsOnError()
counterpart as well.
Updated about 1 year ago