Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Early return not triggered on error in parallel branches beforehand #3865

Closed
wasnertobias opened this issue Jun 3, 2024 · 4 comments · Fixed by #3975
Closed

bug: Early return not triggered on error in parallel branches beforehand #3865

wasnertobias opened this issue Jun 3, 2024 · 4 comments · Fixed by #3975
Assignees
Labels
bug Something isn't working

Comments

@wasnertobias
Copy link

Describe the bug

There are three parallel branches, which are for validation. They throw an error if something is invalid. After this parallel branches a early return is placed, which returns a empty result:

main()
 pass

when a error happens the early return does not actually return, but the flow continues running and returns internal information, which should never be returned

Screenshot 2024-06-03 at 18 39 17

To reproduce

Cannot provide you with a minimum reproducible flow (yet)

Expected behavior

...

Screenshots

No response

Browser information

No response

Application version

EE v1.334.0-1-g4d88dadb1

Additional Context

No response

@wasnertobias wasnertobias added the bug Something isn't working label Jun 3, 2024
@wasnertobias
Copy link
Author

#3701

@rubenfiszel
Copy link
Contributor

Please provide a minimal reproduction and we will investigate

@wasnertobias
Copy link
Author

Alright, so you can use the following one. If using parallel branches or not the behavior changes. Also if defining a own custom error handler or not changes the behavior. My expectation is that in no case (wether parallel or not, wether using a own error handler or not) the code in the last step is never run!

summary: ""
description: ""
value:
  modules:
    - id: ap
      value:
        type: branchall
        branches:
          - expr: ""
            modules:
              - id: at
                value:
                  lock: ""
                  type: rawscript
                  content: |-
                    # import wmill


                    def main(x: str):
                        return x
                  language: python3
                  input_transforms:
                    x:
                      type: static
                      value: ""
                summary: Do stuff
            parallel: true
            skip_failure: false
          - expr: ""
            modules:
              - id: as
                value:
                  lock: ""
                  type: rawscript
                  content: |-
                    # import wmill


                    def main(x: str):
                        return x
                  language: python3
                  input_transforms:
                    x:
                      type: static
                      value: ""
                summary: Do stuff
            summary: ""
            parallel: true
            skip_failure: false
        parallel: true
      summary: ""
    - id: au
      value:
        lock: ""
        type: rawscript
        content: |-
          # import wmill


          def main(x: int):
              return x * 2
        language: python3
        input_transforms:
          x:
            expr: flow_input.x
            type: javascript
      summary: Do stuff
    - id: an
      value:
        type: branchall
        branches:
          - expr: ""
            modules:
              - id: ax
                value:
                  lock: ""
                  type: rawscript
                  content: |-
                    # import wmill


                    def main(x: int):
                        raise PermissionError("blabla3")
                  language: python3
                  input_transforms:
                    x:
                      expr: flow_input.x
                      type: javascript
            parallel: true
            skip_failure: false
          - expr: ""
            modules:
              - id: aw
                value:
                  lock: ""
                  type: rawscript
                  content: |-
                    # import wmill


                    def main():
                        raise PermissionError("blabla")
                  language: python3
                  input_transforms: {}
            summary: ""
            parallel: true
            skip_failure: false
          - expr: ""
            modules:
              - id: am
                value:
                  type: branchone
                  default: []
                  branches:
                    - expr: flow_input.x == 1
                      modules:
                        - id: aa
                          value:
                            tag: ""
                            lock: ""
                            type: rawscript
                            content: |-
                              def main():
                                  raise AssertionError("blabla")
                            language: python3
                            input_transforms: {}
                          summary: ....
                      summary: == 1
                      parallel: true
                      skip_failure: true
                summary: ""
            summary: ""
            parallel: true
            skip_failure: true
        parallel: true
      summary: ""
    - id: ao
      value:
        tag: ""
        lock: ""
        type: rawscript
        content: |-
          def main():
              pass
        language: python3
        input_transforms: {}
      summary: EARLY EMPTY RETURN
    - id: av
      value:
        tag: ""
        lock: ""
        type: rawscript
        content: |-
          import logging

          def main(x: int):
              logging.error("Why is this run?" + str(x*3))
              return x*3
        language: python3
        input_transforms:
          x:
            expr: results.au
            type: javascript
      summary: This should never run because an exception happened before
  early_return: ao
  failure_module:
    id: failure
    value:
      tag: null
      type: rawscript
      content: |-
        import os

        def main(message: str, name: str):
            flow_id = os.environ.get("WM_FLOW_JOB_ID")
            error_message_whitelist = [
                "ValidationError",
                "PermissionError",
                "AssertionError"
            ]

            if name in error_message_whitelist:
                return {
                    'windmill_status_code': 400,
                    'result': {
                        'error': {
                            'name': name,
                            'message': message,
                            'flow_id': flow_id
                        }
                    }
                }
            else:
                return {
                    'windmill_status_code': 400,
                    'result': {
                        'error': {
                            'name': name,
                            'flow_id': flow_id
                        }
                    }
                }
      language: python3
      input_transforms:
        name:
          expr: error.name
          type: javascript
        message:
          expr: error.message
          type: javascript
  concurrency_time_window_s: 0
schema:
  type: object
  additionalProperties: false
  order:
    - x
  properties:
    x:
      type: number
      description: ""
      format: ""
  required: []

@wasnertobias
Copy link
Author

Another example where it WORKS AS EXPECTED with parallel branches and a customer error handler

summary: ""
description: ""
value:
  modules:
    - id: a
      value:
        type: branchall
        branches:
          - expr: ""
            modules:
              - id: e
                value:
                  lock: ""
                  type: rawscript
                  content: |-
                    def main():
                        raise Exception("Example")
                  language: python3
                  input_transforms: {}
            parallel: true
            skip_failure: false
          - expr: "false"
            modules:
              - id: d
                value:
                  tag: ""
                  lock: ""
                  type: rawscript
                  content: |-
                    def main():
                        raise Exception("Example")
                  language: python3
                  input_transforms: {}
            summary: ""
            parallel: true
            skip_failure: false
        parallel: true
      summary: ""
    - id: b
      value:
        lock: ""
        type: rawscript
        content: |-
          def main():
              pass
        language: python3
        input_transforms: {}
      summary: Empty EARLY return
    - id: c
      value:
        tag: ""
        lock: ""
        type: rawscript
        content: |-
          import logging

          def main():
              logging.info("This should never be run")
        language: python3
        input_transforms: {}
  early_return: b
  failure_module:
    id: failure
    value:
      tag: null
      type: rawscript
      content: |-
        import os

        def main(message: str, name: str):
            flow_id = os.environ.get("WM_FLOW_JOB_ID")
            error_message_whitelist = [
                "ValidationError",
                "PermissionError",
                "AssertionError"
            ]

            if name in error_message_whitelist:
                return {
                    'windmill_status_code': 400,
                    'result': {
                        'error': {
                            'name': name,
                            'message': message,
                            'flow_id': flow_id
                        }
                    }
                }
            else:
                return {
                    'windmill_status_code': 400,
                    'result': {
                        'error': {
                            'name': name,
                            'flow_id': flow_id
                        }
                    }
                }
      language: python3
      input_transforms:
        name:
          expr: error.name
          type: javascript
        message:
          expr: error.message
          type: javascript
schema:
  $schema: https://json-schema.org/draft/2020-12/schema
  properties: {}
  required: []
  type: object

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants