final cleanup when shell exceution fails

demo the finally element will guarantee the resource cleanup when shell execution fails

Demo

source

Main task yaml file
    tasks:
    - name: task
      task:
      - func: shell
        desc: |
          task fails
        do:
        - echo "open a file ....."
        - echo "reading the file" |grep "cause an exception"
        finally: close_file
      - func: cmd
        desc: step 2
        do:
        - name: print
          cmd: step 2
    - name: close_file
      task:
      - func: shell
        name: close_file
        desc: |
          ensure the opened file is closed
        do:
        - echo "close the file ....."
    
Main log file
    loading [Config]:  ./tests/functests/upconfig.yml
    Main config:
                 Version -> 1.0.0
                  RefDir -> ./tests/functests
                 WorkDir -> cwd
              AbsWorkDir -> /up_project/up
                TaskFile -> f0171
                 Verbose -> vvv
              ModuleName -> self
               ShellType -> /bin/sh
           MaxCallLayers -> 8
                 Timeout -> 3600000
     MaxModuelCallLayers -> 256
               EntryTask -> task
      ModRepoUsernameRef -> 
      ModRepoPasswordRef -> 
    work dir: /up_project/up
    -exec task: task
    loading [Task]:  ./tests/functests/f0171
    module: [self], instance id: [dev], exec profile: []
    profile -  envVars:
    
    (*core.Cache)({
    })
    
    Task1: [task ==> task:  ]
    -Step1: [
    task fails
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 0
    })
    
    cmd( 1):
    echo "open a file ....."
    
    -
    open a file .....
    
    -
     .. ok
    cmd( 2):
    echo "reading the file" |grep "cause an exception"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
    Step Finally:
    =Task2: [task ==> close_file:  ]
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_shell_exec_result": (*utils.ExecResult)({
        Cmd: "echo \"reading the file\" |grep \"cause an exception\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "up_runtime_task_layer_number": 1
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
     WARN: [Not rescued in task level] - [please assess the panic problem and cause, fix it before re-run the task]
    task finally ->   ERROR: Failed And Not Ignored! [You may want to continue and ignore the error]
    
    
Logs with different verbose level
Raw logs with different verbose level

what will happen if there is no ignoreError for the task

The shell step failed, the finally step invokes the close_file task to ensure the opened file is closed

In this way, user has the control to gracefully cleanup all relevant resources used and terminate the process to continue further. The task fails, but it is intended.

In case user would like to continue, use can still choose to use ignoreError, then it will continue to execute the “step 2”

Other references: