Apama 10.15.0 | Developing Apama Applications | Developing Apama Applications in EPL | Defining What Happens When Matching Events Are Found | Exception handling
 
Exception handling
EPL supports the try ... catch exception handling structure. The statements in each block must be enclosed in curly braces. For example:
using com.apama.exceptions.Exception;
...
action getExchangeRate(
dictionary<string, string> prices, string fxPair) returns float {
try {
return float.parse(prices[fxPair]);
} catch(Exception e) {
return 1.0;
}
}
Exceptions are a mechanism for handling runtime errors. Exceptions can be caused by any of the following, though this is not an exhaustive list:
*Invalid operations such as trying to divide an integer by zero, or trying to access a non-existent entry in a dictionary or sequence
*Methods that fail, for example trying to parse an object that cannot be parsed
*Plug-ins
*Operations that are illegal in certain states, such as spawn-to in an ondie() or onunload() action, or sending an event to a context and specifying a variable that has not been assigned a valid context object
*The throw statement. See The throw statement for more information.
An exception that occurs in try block1 causes execution of catch block2. An exception in try block1 can be caused by:
*Code explicitly in try block1
*A method or action called by code in try block1
*A method or action called by a method or action called by code in try block1, and so on.
Note that the die statement always terminates the monitor, regardless of try ... catch statements.
The variable specified in the catch clause must be of the type com.apama.exceptions.Exception. Typically, you specify using com.apama.exceptions.Exception to simplify specification of exception variables in your code. The Exception variable describes the exception that occurred.
The com.apama.exceptions namespace also contains the StackTraceElement built-in type. The Exception and StackTraceElement types are always available; you do not need to inject them and you cannot delete them with the engine_delete utility.
An Exception type has methods for accessing:
*A message — Human-readable description of the error, which is typically useful for logging.
*A type — Name of the category of the exception, which is useful for comparing to known types to distinguish the type of exception thrown. Internally generated exceptions have types such as ArithmeticException and ParseException. For a list of exception types, see the description of the Exception type in the API Reference for EPL (ApamaDoc) .
*A stack trace — A sequence of StackTraceElement objects that describe where the exception was thrown. The first StackTraceElement points to the place in the code that immediately caused the exception, for example, an attempt to divide by zero or access a dictionary key that does not exist. The second StackTraceElement points to the place in the code that called the action that contains the immediate cause. The third StackTraceElement element points to the code that called that action, and so on. Each StackTraceElement object has methods for accessing:
*The name of the file that contains the relevant code
*The line number of the relevant code
*The name of the enclosing action
*The name of the enclosing event, monitor or aggregate function
Information in an Exception object is available by calling these built-in methods:
*Exception.getMessage()
*Exception.getType()
*Exception.getStackTrace()
*StackTraceElement.getFilename()
*StackTraceElement.getLineNumber()
*StackTraceElement.getActionName()
*StackTraceElement.getTypeName()
In the catch block, you can specify corrective steps, such as returning a default value or logging an error. By default, execution continues after the catch block. However, you can specify the catch block so that it returns, dies or causes an exception.
You can nest try ... catch statements in a single action. For example:
action NestedTryCatch() {
try {
print "outer";
try {
print "inner";
integer i:=0/0;
} catch(Exception e) {
// inner catch
}
} catch(Exception e) {
// outer catch
}
}
The block in a try clause can specify multiple actions and each one can contain a try ... catch statement or nested try ... catch statements. An exception is caught by the innermost enclosing try ... catch statement, either in the action where the exception occurs, or walking up the call stack. If an exception occurs and there is no enclosing try ... catch statement then the correlator logs the stack trace of the exception and terminates the monitor instance.
See About executing ondie() actions for information about how ondie() can optionally receive exception information if an instance dies due to an uncaught exception.