camundacamunda-modelercamunda-plugincamunda-spin

Halt the workflow and return the response to Controller


  1. Create Order triggers the Rest End point and starts the workflow (Its a TASK ). CreateOrderController

Problem is CreateOrderController is always returning Success.I want to return ResponseEntity.ok("Not Success "); as shown in 2nd image and stop the call of Save Order Database How to achieve it?

> @RestController
> public class CreateOrderController {
> 
>   @Autowired
>   private RuntimeService runtimeService;
> 
> 
> 
>   @PostMapping("/rest/create/order")
>   public ResponseEntity<?> createOrder(@RequestBody OrderInfo orderInfo) {
> Map<String, Object> inputData = new HashMap<String, Object>();
>       inputData.put("orderInfo", orderInfo);
>      ProcessInstance p = runtimeService.startProcessInstanceByKey("hello-world-process",inputData);
>      
>      
> 
>       return ResponseEntity.ok("Success");
> 
>   }

enter image description here enter image description here

enter image description here


Solution

  • If you are executing the complete process in one transaction, then an exception along the way will create a rollback. However, you usually have a transaction boundary somewhere. You can query the status of the process instance after it has been started via the history endpoint.

    The execute method returns void. Let the delegate write process data instead of returning a value. You can find a setVariable method on the delegateExecution you are getting in as a parameter.

    You can get the data values in the REST response as shown in this example: https://docs.camunda.org/manual/7.18/reference/rest/process-definition/post-start-process-instance/#starting-a-process-instance-with-variables-in-return

    Request:

    {
     "variables":{
       "aVariable" : {
         "value" : "aStringValue",
         "type": "String"},
       "anotherVariable" : {
         "value" : true,
         "type": "Boolean",
         "valueInfo" : {
            "transient" : true
          }
        }
     },
     "businessKey" : "myBusinessKey",
     "withVariablesInReturn": true
    }
    

    Response

    {
      "links": [
        {
          "method": "GET",
          "href": "http://localhost:8080/rest-test/process-instance/aProcInstId",
          "rel": "self"
        }
      ],
      "id": "aProcInstId",
      "definitionId": "aProcessDefinitionId",
      "businessKey": "myBusinessKey",
      "ended": false,
      "suspended": false,
      "tenantId": null,
      "variables": {
        "anotherVariable": {
            "type": "Boolean",
            "value": true,
            "valueInfo": {
              "transient" : true
            }
        },
        "aVariable": {
            "type": "String",
            "value": "aStringValue",
            "valueInfo": { }
        }
      }
    }
    

    Alternatively, error handling options in the delegate code / process include:

    a) Simply throw an exception in your execute() method, for instance a new RuntimeException() and observe in Cockpit how Camunda creates a technical incident for the process (https://docs.camunda.org/manual/7.18/webapps/cockpit/bpmn/failed-jobs/).

    b) You can also use custom exceptions and error codes, e.g. as shown here:

    // Defining a custom exception.
    public class MyException extends ProcessEngineException {
    
      public MyException(String message, int code) {
        super(message, code);
      }
    }
    
    // Delegation code that throws MyException with a custom error code.
    public class MyJavaDelegate implements JavaDelegate {
    
      @Override
      public void execute(DelegateExecution execution) {
        String myErrorMessage = "My error message.";
        int myErrorCode = 22_222;
        throw new MyException(myErrorMessage, myErrorCode);
      }
    
    }
    

    Src: https://docs.camunda.org/manual/7.18/user-guide/process-engine/delegation-code/#exception-codes

    c) If you don't want to create e technical incident but prefer to throw a 'business' error which you can catch in the process model, so the process can take a different (error) path:

    public class BookOutGoodsDelegate implements JavaDelegate {

      public void execute(DelegateExecution execution) throws Exception {
        try {
            ...
        } catch (NotOnStockException ex) {
            throw new BpmnError("Business issue");
        }
      }
    
    }
    

    src: https://docs.camunda.org/manual/7.18/user-guide/process-engine/delegation-code/#throw-bpmn-errors-from-delegation-code