(WMB) Error handling
When we design any message flow, we often do not give more emphasis on error handling. Well as per my experience I found this error handling techniques & design principles more crucial than designing the happy path.
So here I am with few details on how to handle unhappy path in WMBV6.0 with information about the message flow error behavior.
Design Consideration
· Connect the Failure terminal of any node to a sequence of nodes that processes the node's internal exception (the Failure flow).
· Connect the Catch terminal of the input node or a TryCatch node to a sequence of nodes that processes exceptions that are generated beyond it (the Catch flow).
· Insert one or more TryCatch nodes at specific points in the message flow to catch and process exceptions that are generated by the flow that is connected to the Try terminal.
· Ensure that all messages that are received by an MQInput node are processed within a transaction or are not processed within a transaction.
Understanding the Flow Sequence
· When an exception is detected within a node, the message and the exception information are propagated to the node's Failure terminal ( Diagnostic information is available in the ExceptionList).
· If the node does not have a Failure terminal or if it is not connected, the broker throws an exception and returns control to the closest previous node that can process the exception. This node can be a TryCatch node (Root & LocalEnvironment are reset to the values they had before) or the MQInput node .
· If the catch terminal of the MQInput node is connected, the message is propagated there (ExceptionList entries are available; Root & LocalEnvironment are reset to the values they had before).
1) If message is transactional and catch terminal is connected ,then message goes to catch terminal and thrown to Input node due to Throw node in Catch.And then backout count is checked.And based upon backout count,message is retried.Finally message goes to Failure terminal if it is connected.If Failure terminal is not connected,then Backout Q or System DLQ is checked.
2) If message is not transactional and catch terminal is connected,then message goes to catch terminal and thrown to Input node due to Throw node in Catch. But backout count is not checked and also does not go to Failure terminal even if it is connected and it is discarded.
What if in Failure path,there is some error?
Error path should be properly handled by Failure terminal's subsequent nodes.Otherwise,successive errors will be discarded.
Otherwise if the catch terminal is not connected, the transactionality of the message is considered.
· If the message is not transactional, the message is discarded. Otherwise , if it is transactional, the message is returned to the input queue, and it is read again, whereupon the backout count is checked.
· If the backout count has not exceeded its threshold, the message is propagated to the output terminal of the MQInput node for reprocessing. Otherwise if it is exceeded & if the failure terminal of the MQInput node is connected then the message is propagated to that path. (Root is available but ExceptionList is empty)
· If the failure terminal of the MQInput node is not connected, the message is put on an available queue, in order of preference; message is put in backout queue, if one is defined; otherwise in dead-letter queue, if one is defined. If the message cannot be put on either of these queues, it remains on the input queue in a retry loop until the target queue clears.(It also records the error situation by writing errors to the local error log)
The below are the info that can be captured from the ExceptionList:
· MessageId of the incoming message
· Flow name(Name of the message flow in which exception has occurred)
· Node name in which the exception has occurred
· Error time (Time when the exception has occurred)
· Error Number (Error Number for the exception which is generated by Message broker)
· Error Severity(Severity of the exception)
· ErrorDetails(Complete description of the error)
My testing scenarios:
With Javacompute node:
Input queue -àHas Backout queueàBackout threshold =3
1) Scenario:
Javacompute node has exception catching code as below.
Message flow nodes’ Failure and Catch are not connected
Transactionality is “YES”,
catch (SQLException sqx ){
MbUserException mbue = new MbUserException(this, "evaluate()", "","", sqx.toString(), null);
throw mbue;
}
Observation:
· Error thrown to MQInput node
· Message is retrying with Backout count in MQMD as 1,2,3 consecutively
2)Scenario:
Javacompute node has exception catching code
MQInput node’s catch is connected
Transactionality is “YES”
Exception handling subflow ends with MQOUTPUT node (ERRORQ)
Observation:
· Error thrown to MQInput node
· Exception once thrown to MQInput node,is sent to catch terminal
· The message is written to MQOUTPUT node (ERRORQ).This message written has only original message
· Retry is not actually performed because the message is not thrown to the input queue.
3)Scenario
Javacompute node does not have exception catching code .Just like below,
catch (SQLException sqx ){
}
MQInput node’s catch is connected
Transactionality is “YES”
Exception handling subflow ends with MQOUTPUT node (ERRORQ)
The below Exceptionlist populating message is written in subflow,
DECLARE start REFERENCE TO InputExceptionList.*[1];
WHILE start.Number IS NOT NULL DO
SET OutputRoot.XML.Exception.messageNumber = start.Number;
SET OutputRoot.XML.Exception.messageText = start.Text;
MOVE start LASTCHILD;
END WHILE;
Observation:
Behaved same as Scenario 2 but the message at output is,
hi
<Exception>
<messageNumber>6233</messageNumber>
<messageText>Problem encountered obtaining JDBC connection</messageText>
</Exception>
4)Scenario
Only if it is connectivity failure,the code has to retry.
Otherwise the code should not retry