I have a set of process steps in the process.xaml which are a unit of work that needs to be retried if it does not complete successfully. It is in a Try/Catch block. If a system error occurs it drops into the Catch sequence. However when the process.xaml exits and returns to the GetTransaction state it doesn’t recognise a system exception,drops into the SetTransactionStatus sequence and sets the transaction to Success, so it does not retry. I obviously have missed something obvious about how this is meant to work. Can anyone point me in the right direction.
It looks like your Try/Catch block is preventing any exceptions to be raised in order for the REFramework to handle them correctly. The Catch portion of the Try/Catch is catching the exception and the process is continuing on thinking that the transaction was successful. You can fix this two ways:
Remove the Try/Catch block so that any system errors will trigger the REFramework to set the Transaction Status to System Error.
OR
If you still want to use a try catch block, place a “Rethrow” activity inside the Catch portion of the Try/Catch block as the last activity. This will Rethrow the exception that was caught and throw it to a higher level so that the REFramework can handle it.
I first of all tested the business exception process, so not the system exception you addressed above, which I will get to later. The basic scenario is some business data is incorrect and the transaction needs to be failed. I am struggling (as usual on this!) to work out how you set the status to a business exception. If you Throw an exception it stops the workflow. What I want is to trap the error, set the “status” to a business exception, log a message, drop back up to the calling module and let it follow the set transaction status logic path for a business exception. The appplication logic can only know its a business exception if I tell it, the issue I have is how to do that without stopping the workflow in its tracks. I expect you will know the answer!
The ideal way to handle exceptions where you want to retry is to identify where these exceptions are occurring and write the process to throw a BusinessRuleException whenever the error occurs.
However, if you don’t want to code for each scenario, you can put the process in a Try Catch block and in the Catch, assign the System Error to the Business Exception instead. Just make sure you’re still outputting the useful information behind the error for helpful logging purposes.
For throwing a business exception, you can handle this by using the second scenario I stated above with a few modifications. Within the Try portion of the Try/Catch block, you want to use the Throw activity and in the Exception property you can write new BusinessRuleException("Your Exception Goes Here") and this will now throw a Business Rule Exception. Please see below.
Now that you threw a Business Rule Exception in the Try portion of the Try/Catch Block, you want to place your Log and Rethrow activity in the Catch portion so that the REFramework will handle the business exception.
I have coded for the event. On the event occurring I thought I could add a Throw activity with the property of New BusinessRuleException(“user defined message”) and the system would recognise that
a Business Exception had been thrown. I am using the REFramework and my problem is that I want this business exception to be picked up in the Process state when the process.xaml completes, so that when the logic invokes the SetTransactionStatus workflow it
sees that there is a business exception and routes the logic down the Fail path rather than the Success path. I am unable to work out how you set the Business Exception as not Nothing, so that the logic finds the Fail path. When the process.xaml completes
it is treated as a successful transaction. I don’t have this problem with system exceptions, because they appear to be picked up automatically if a UI element isn’t found or whatever. But a business exception requires the application code to recognise there
is a problem and do something to set the status to Business Exception.
Do you want the process to end after a business exception (go to the End state) or act as it would were this a system exception (i.e. go to the Init state, then Get Transaction Data, then Process).
If it is the latter, you can create a new transition from the Process state that leads to the End state. Have the process go here when the BusinessException is not nothing, and delete the old transition for BusinessExceptions.
Thanks for the reply. I had set up the Throw as you indicated. Do I put the
Log and ReThrow in the Catch of the same sequence, or do you mean at the higher level? I think from your previous message you were saying that a ReThrow “throws” it up to the next level, so I assume in the same sequence and then it will be detected at the next level up? Also this workflow is invoked from the Process.xaml, so it needs to ripple up to the Process state where the Process.xaml is called from.
Many thanks this worked. Throw the Business Exception in the Try and then a ReThrow in the Catch and this is then picked up at the higher levels and routes through the Business Exception path of the SetTransactionStatus workflow setting the transaction status to Failed.
Therefore you don’t need to surround anything inside the process.xaml, because if an Exception is happening (thrown by any activity when it fails), it will be handled by REFramework itself. (as Business or System exception)
If you want, you can still handle the error yourself, by doing something when the error happens, such as create a log in a log text/excel file, or log message to create log in output window/orchestrator. Or just handle it any different way, like pause, wait for correct input or whatever, up to your imagination, wait in a loop for the error is corrected, for example a person types the correct data, valid email, or whatever.
But anyways, if you handle it yourself in REFramework, then in the orchestrator it may appear as a ‘success’. (unless when you handle it you use Set Transaciton Status activity by yourself and set the status differently).
If you want a combination of YOU + REFramework both to handling it. You still do try-catch, but you need to rethrow the same error after you handled it, so REFramework can ‘catch’ it.
(just add a rethrow in the catch block of your own try-catch), example like:
But mostly that is the good thing about REFramework, that it is why it was designed, to handle the errors/logging. (by “errors” I mean catching Exceptions)
It would be an example of Try catch in a Try catch (like here):