complex task finally in sub task

Showcases comlex sub task with finally block

Demo

source

Main task yaml file
    TODO:
    tasks:
    - name: task
      task:
      - func: block
        loop:
        - item1
        - item2
        desc: task
        do:
        - func: call
          do: sub_task_layer1
    - name: sub_task_layer1
      desc: sub_task_layer1
      task:
      - func: cmd
        do:
        - name: print
          cmd: "in sub_task_layer1"
      - func: block
        loop:
        - aaaa
        - bbbb
        desc: task
        do:
        - func: cmd
          desc: processing .....
          do:
          - name: print
            cmd: '{{.loopitem}}'
        - func: call
          loop:
          - xxx
          - yyy
          do:
          - sub_task_layer2
    - name: sub_task_layer2
      task:
      - func: shell
        name: step1
        desc: step 1
        flags: [ignoreError]
        do:
        - 'echo """opening file: {{.loopitem}}"""'
        - echo "hello"|grep "world"
      - func: cmd
        name: step2
        desc: |
          in this case, since there is no ignoreError, the exception was captured by task level finaly code block
          opened file is safely closed
          to make the flow to continue to reach step2, use ignoreError
        do:
        - name: print
          cmd: step 2
      desc: |
        without rescue, the execution will return a non-zero  return code in shell and also report the error
        with rescue, the program will return 0
      rescue: true
      finally:
      - 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 -> c0187
                 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/c0187
    module: [self], instance id: [dev], exec profile: []
    profile -  envVars:
    
    (*core.Cache)({
    })
    
    Task1: [task ==> task:  ]
    -Step1: [: task ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 0
    })
    
    -Step1:
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 0,
      "loopitem": "item1",
      "loopindex": 0,
      "loopindex1": 1
    })
    
    =Task2: [task ==> sub_task_layer1: sub_task_layer1 ]
    --Step1:
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 1,
      "up_runtime_task_layer_number": 1,
      "loopitem": "item1",
      "loopindex": 0
    })
    
    ~~SubStep1: [print:  ]
    in sub_task_layer1
    --Step2: [: task ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 1,
      "loopitem": "item1",
      "loopindex": 0,
      "loopindex1": 1
    })
    
    --Step1: [: processing ..... ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 1,
      "up_runtime_task_layer_number": 1,
      "loopitem": "aaaa",
      "loopindex": 0
    })
    
    ~~SubStep1: [print:  ]
    aaaa
    --Step2:
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 1,
      "loopitem": "aaaa",
      "loopindex": 0,
      "loopindex1": 1
    })
    
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopitem": "xxx",
      "loopindex": 0,
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: xxx
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0,
      "loopindex1": 1
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"close the file .....\"",
        Code: 0,
        Output: "close the file .....",
        ErrMsg: ""
      }),
      "up_runtime_task_layer_number": 2
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: yyy
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 2,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "loopindex": 1
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2,
      "up_runtime_task_layer_number": 2
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    --Step1: [: processing ..... ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 1,
      "loopitem": "bbbb",
      "loopindex": 1,
      "loopindex1": 2
    })
    
    ~~SubStep1: [print:  ]
    bbbb
    --Step2:
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex": 1,
      "loopindex1": 2,
      "up_runtime_task_layer_number": 1,
      "loopitem": "bbbb"
    })
    
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: xxx
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "loopindex": 0,
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx"
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex": 0,
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx"
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"close the file .....\"",
        Code: 0,
        Output: "close the file .....",
        ErrMsg: ""
      }),
      "loopindex": 1,
      "loopindex1": 2
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: yyy
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "loopindex": 1,
      "loopindex1": 2,
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy"
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex": 1,
      "loopindex1": 2,
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy"
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    -Step1:
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 2,
      "up_runtime_task_layer_number": 0,
      "loopitem": "item2",
      "loopindex": 1
    })
    
    =Task2: [task ==> sub_task_layer1: sub_task_layer1 ]
    --Step1:
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 1,
      "loopitem": "item2",
      "loopindex": 1,
      "loopindex1": 2
    })
    
    ~~SubStep1: [print:  ]
    in sub_task_layer1
    --Step2: [: task ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 2,
      "up_runtime_task_layer_number": 1,
      "loopitem": "item2",
      "loopindex": 1
    })
    
    --Step1: [: processing ..... ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex": 0,
      "loopindex1": 1,
      "up_runtime_task_layer_number": 1,
      "loopitem": "aaaa"
    })
    
    ~~SubStep1: [print:  ]
    aaaa
    --Step2:
    self: final context exec vars:
    
    (*core.Cache)({
      "loopitem": "aaaa",
      "loopindex": 0,
      "loopindex1": 1,
      "up_runtime_task_layer_number": 1
    })
    
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex": 0,
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx"
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: xxx
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 1,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 1,
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"close the file .....\"",
        Code: 0,
        Output: "close the file .....",
        ErrMsg: ""
      }),
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: yyy
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      })
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    --Step1: [: processing ..... ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopindex1": 2,
      "up_runtime_task_layer_number": 1,
      "loopitem": "bbbb",
      "loopindex": 1
    })
    
    ~~SubStep1: [print:  ]
    bbbb
    --Step2:
    self: final context exec vars:
    
    (*core.Cache)({
      "loopitem": "bbbb",
      "loopindex": 1,
      "loopindex1": 2,
      "up_runtime_task_layer_number": 1
    })
    
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0,
      "loopindex1": 1
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: xxx
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0,
      "loopindex1": 1,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      })
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "xxx",
      "loopindex": 0,
      "loopindex1": 1
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    ==Task3: [task/sub_task_layer1 ==> sub_task_layer2: without rescue, the execution will return a non-zero  return code in shell and also report the error
    with rescue, the program will return 0
     ]
    ---Step1: [step1: step 1 ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"close the file .....\"",
        Code: 0,
        Output: "close the file .....",
        ErrMsg: ""
      })
    })
    
    cmd( 1):
    echo """opening file: {{.loopitem}}"""
    
    -
    opening file: yyy
    
    -
     .. ok
    cmd( 2):
    echo "hello"|grep "world"
    
    -
    
    -
     .. failed(suppressed if it is not the last step)
     WARN: [ignoreError:] - [Error ignored!!!]
    ---Step2: [
    step2in this case, since there is no ignoreError, the exception was captured by task level finaly code block
    opened file is safely closed
    to make the flow to continue to reach step2, use ignoreError
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2,
      "last_result": (*utils.ExecResult)({
        Cmd: "echo \"hello\"|grep \"world\"",
        Code: 1,
        Output: "",
        ErrMsg: "exit status 1"
      }),
      "up_runtime_task_layer_number": 2
    })
    
    ~~~SubStep1: [print:  ]
    step 2
    task Finally:
    --Step1: [
    close_fileensure the opened file is closed
    ]
    self: final context exec vars:
    
    (*core.Cache)({
      "up_runtime_task_layer_number": 2,
      "loopitem": "yyy",
      "loopindex": 1,
      "loopindex1": 2
    })
    
    cmd( 1):
    echo "close the file ....."
    
    -
    close the file .....
    
    -
     .. ok
    . ok
    
Logs with different verbose level
Raw logs with different verbose level

What’s the difference betwee the step level and task level finally cleanup and rescue?

The only difference would be that in the step level, you would be able to obtain the exec result and then conditionally do something about it

Other references: