Here the logic:
Custom Task
is a custom WorkItemHandler, the simple implementation is
Input
parameterResult
string with the concatenation of Hello
and the value of the Input
Input
matches one of the following values RETRY
, COMPLETE
, ABORT
or RETHROW
; it throws a ProcessWorkItemHandlerException
initialized with the corresponding strategyPrint Message
is script which print out the outcome of the previous Task (stored in message
variable).
Finally, an event sub-process is defined to catch all exceptions that reach the main process instance and to print out Catch all
in the console.
In short, it is a sophisticated version of a Hello World process!
In order to probe the Error Handling capabilities, you have to trigger the process with the name of the error handling strategy. Regardless the strategy, the sub-process error-handling
will be executed, then the main process execution is influenced by the strategy:
RETRY
: the Custom Task
is executed again, the Input
parameter of the task is refreshed using the outcome of the error-handling
process.COMPLETE
: the Custom Task
is skipped, the Result
parameter of the task is set with the corresponding outcome of the error-handling
process.ABORT
: the Custom Task
is aborted and the process instance continues the execution. Pay attention: if the outcome of the task is essential for the following tasks the process is going to fail later).RETHROW
: the Custom Task
is aborted and the exception is thrown back at the task scope.The error-handling
sub-process initiates a user task which goal is to repair the situation.
The process design leaves the user in full control:
RETRY
, they can provide a different input parameter for the taskCOMPLETE
, they can set the output parameter result for the task, in other words, the user replaces the implementation of the task by simulating a responseHere the process model:
The Init
script calls the corresponding method of the class ErrorHandlingScript
and there it performs the following:
strategy
process variableThe Apply
script calls the corresponding method of the class ErrorHandlingScript
and there it performs the following:
strategy
variableError
variable with a new ProcessWorkItemHandlerException
initialized with the new strategyYou will need:
When using native image compilation, you will also need:
mvn clean compile quarkus:dev
NOTE: With dev mode of Quarkus you can take advantage of hot reload for business assets like processes, rules, decision tables and java code. No need to redeploy or restart your running application.
mvn clean package java -jar target/quarkus-app/quarkus-run.jar
or on windows
mvn clean package java -jar target\quarkus-app\quarkus-run.jar
Note that the following configuration property needs to be added to application.properties
in order to enable automatic registration of META-INF/services
entries required by the workflow engine:
quarkus.native.auto-service-loader-registration=true
Note that this requires GRAALVM_HOME to point to a valid GraalVM installation
mvn clean package -Pnative
To run the generated native executable, generated in target/
, execute
./target/process-error-handling-runner
You can take a look at the OpenAPI definition - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available Swagger UI.
In addition, various clients to interact with this service can be easily generated using this OpenAPI definition.
When running in either Quarkus Development or Native mode, we also leverage the Quarkus OpenAPI extension that exposes Swagger UI that you can use to look at available REST endpoints and send test requests.
To make use of this application it is as simple as putting a sending request to http://localhost:8080/hello_error
with following content
{ "name" : "john" }
Complete curl command can be found below:
curl --request POST \ --url http://localhost:8080/hello_error \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{"name" : "john"}'
Response should resemble:
{ "id": "ae4a5fd4-3d49-4ba5-92dd-4b6222492fdd", "message": "Hello john" }
TIP: In the following example, we are going to show the
curl
command line. Although, a more comfortable way is using the following REST client, you can find in the project the file with all the requests:src/test/http/error-handling.http
.
Trigger the process with any error handling strategy:
curl --request POST \ --url http://localhost:8080/hello_error \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{"name" : "RETRY"}'
An error-handling
process instance is created.
Get the user tasks
curl http://localhost:8080/usertasks/instance?user=jdoe
Complete the Repair
task.
curl -X POST "http://localhost:8080/usertasks/instance/{userTaskId}/transition?user=jdoe" -H "content-type: application/json" -d '{"transitionId": "complete","data": {"input" : "Jimmy", "strategy" : "RETRY", "approve": true}}'
The WIH logic is executed again using the new input parameter provided by the error-handling
process.
In the console you should spot an output the resemble the following:
2021-09-22 19:27:29,688 DEBUG [org.acm.wih.CustomTaskWorkItemHandler] (executor-thread-0) strategy = RETRY >>> message: Hello Jimmy 2021-09-22 19:27:29,689 DEBUG [org.acm.wih.CustomTaskWorkItemHandler] (executor-thread-0) end
Follow all the step in the previous paragraph, but complete the Repair
task providing a different payload.
Complete strategy The WIH logic is skipped but the task is marked completed, the main process proceeds picking the result provided by the error-handling
process
curl -X POST "http://localhost:8080/usertasks/instance/{userTaskId}/transition?user=jdoe" -H "content-type: application/json" -d '{"transitionId": "complete","data": {"result" : "Hello Jimmy", "strategy" : "COMPLETE", "approve": true}}'
From the console output you should spot this line:
>>> message: Hello Jimmy
Abort strategy The WIH logic is skipped and the task is marked aborted, the main process proceeds but the Custom Task
result is null.
curl -X POST "http://localhost:8080/usertasks/instance/{userTaskId}/transition?user=jdoe" -H "content-type: application/json" -d '{"transitionId": "complete","data": {"strategy" : "ABORT", "approve": true}}'
From the console output you should spot this line:
>>> message: null
Rethrow strategy The WIH logic is skipped and the main process get an exception
curl -X POST "http://localhost:8080/usertasks/instance/{userTaskId}/transition?user=jdoe" -H "content-type: application/json" -d '{"transitionId": "complete","data": {"strategy" : "RETHROW", "approve": true}}'
From the console output you should spot this line:
Catch all