turbot / pipe-fittings

Shared components for use across pipe projects.
https://github.com/turbot
GNU Affero General Public License v3.0
12 stars 4 forks source link

When using a default value of the wrong type for an arg, or if passed explicitly, the error is not shown with local pipeline run #262

Closed cbruno10 closed 7 months ago

cbruno10 commented 10 months ago

If I have a pipeline with a param whose default value is type string, but the actual type is list(string):

pipeline "list_channels" {
  title       = "List Channels"
  description = "Lists all channels in a Slack team."

  param "cred" {
    type        = string
    description = "Name for credentials to use. If not provided, the default credentials will be used."
    default     = "default"
  }

  param "types" {
    type        = list(string)
    default     = "public_channel"
    description = "Mix and match channel types by providing a comma-separated list of any combination of public_channel, private_channel, mpim, im."
  }

  param "exclude_archived" {
    type        = bool
    default     = false
    description = "Set to true to exclude archived channels from the list."
  }

  step "http" "list_channels" {
    url    = "https://slack.com/api/conversations.list"
    method = "get"

    request_headers = {
      Content-Type  = "application/json; charset=utf-8"
      Authorization = "Bearer ${credential.slack[param.cred].token}"
    }

    request_body = jsonencode(
      merge({types = join(",", param.types)}, { for name, value in param : name => value if value != null && !contains(["cred", "types"], name) })
    )

    throw {
      if      = result.response_body.ok == false
      message = try(result.response_body.error, "")
    }
  }

  output "channels" {
    description = "List of channel details."
    value       = try(step.http.list_channels.response_body.channels, [])
  }
}

And I run flowpipe run list_channels with valid or invalid credentials, and do not pass a value for --arg 'types=..., the pipeline fails but doesn't show me the error:

cbruno@M1P slack % fpr list_channels
[Execution] exec_cln2a2fe58clddtfsivg
[list_channels] Starting: pexec_cln2a2fe58clddtfsj00
[list_channels] Failed with 1 error(s) 1ms
cbruno@M1P slack % cat .flowpipe/store/exec_cln2a2fe58clddtfsivg.jsonl
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"command.pipeline_queue","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.294136Z"},"name":"slack.pipeline.list_channels","args":null,"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00"}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"handler.pipeline_queued","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.295463Z"},"name":"slack.pipeline.list_channels","args":null,"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00"}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"command.pipeline_load","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.295898Z"},"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00"}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"handler.pipeline_loaded","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.299394Z"},"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00","pipeline":{"name":"","pipeline_name":"slack.pipeline.list_channels","steps":[{"name":"list_channels","step_type":"http","pipeline_name":"slack.pipeline.list_channels","credential_depends_on":["slack.\u003cdynamic\u003e"],"throw":[{"if":false,"message":"","unresolved":true}],"url":"https://slack.com/api/conversations.list","method":"get"}],"outputs":[{"name":"channels","description":"List of channel details.","depends_on":["http.list_channels"]}],"params":{"cred":{"name":"cred","description":"Name for credentials to use. If not provided, the default credentials will be used."},"exclude_archived":{"name":"exclude_archived","description":"Set to true to exclude archived channels from the list."},"types":{"name":"types","description":"Mix and match channel types by providing a comma-separated list of any combination of public_channel, private_channel, mpim, im."}}}}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"command.pipeline_start","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.300476Z"},"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00"}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"handler.pipeline_started","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.300731Z"},"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00"}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"command.pipeline_plan","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.300971Z"},"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00"}}
{"level":"info","ts":"2023-12-04T19:14:17Z","caller":"command","msg":"es","event_type":"handler.pipeline_failed","payload":{"event":{"execution_id":"exec_cln2a2fe58clddtfsivg","created_at":"2023-12-04T19:14:17.302242Z"},"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00","error":[{"pipeline_execution_id":"pexec_cln2a2fe58clddtfsj00","step_execution_id":"","pipeline":"slack.pipeline.list_channels","step":"list_channels","error":{"instance":"fperr_cln2a2fe58clddtfsj10","type":"error_internal","title":"Internal Error","status":500,"detail":"list_channels: Invalid function argument: Invalid value for \"lists\" parameter: list of string required.\n(/Users/cbruno/flowpipe/slack/pipelines/channel/list_channels.fp:35,32-43)\nUnsuitable value type: Unsuitable value: value must be known\n(/Users/cbruno/flowpipe/slack/pipelines/channel/list_channels.fp:34,20-31)\n"}}],"pipeline_output":null}}
cbruno10 commented 10 months ago

If I instead run fpr list_channels --arg cred=my_slack --arg types=badstring, I get a different error in the terminal:

cbruno@M1P slack % fpr list_channels --arg cred=my_slack --arg types=badstring
Error: Error executing pipeline - Bad Request: Bad Request: unable to parse value has HCL expression: badstring

In my log store though, the error appears the same as the logs in the first message:

cbruno@M1P slack % cat .flowpipe/store/exec_cln2gm7e58clk12jrrt0.jsonl
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"command.pipeline_queue","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.545409Z"},"name":"slack.pipeline.list_channels","args":{"cred":"my_slack"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg"}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"handler.pipeline_queued","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.547642Z"},"name":"slack.pipeline.list_channels","args":{"cred":"my_slack"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg"}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"command.pipeline_load","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.548305Z"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg"}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"handler.pipeline_loaded","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.549469Z"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg","pipeline":{"name":"","pipeline_name":"slack.pipeline.list_channels","steps":[{"name":"list_channels","step_type":"http","pipeline_name":"slack.pipeline.list_channels","credential_depends_on":["slack.\u003cdynamic\u003e"],"throw":[{"if":false,"message":"","unresolved":true}],"url":"https://slack.com/api/conversations.list","method":"get"}],"outputs":[{"name":"channels","description":"List of channel details.","depends_on":["http.list_channels"]}],"params":{"cred":{"name":"cred","description":"Name for credentials to use. If not provided, the default credentials will be used."},"exclude_archived":{"name":"exclude_archived","description":"Set to true to exclude archived channels from the list."},"types":{"name":"types","description":"Mix and match channel types by providing a comma-separated list of any combination of public_channel, private_channel, mpim, im."}}}}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"command.pipeline_start","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.550975Z"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg"}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"handler.pipeline_started","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.551272Z"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg"}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"command.pipeline_plan","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.551579Z"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg"}}
{"level":"info","ts":"2023-12-04T19:28:24Z","caller":"command","msg":"es","event_type":"handler.pipeline_failed","payload":{"event":{"execution_id":"exec_cln2gm7e58clk12jrrt0","created_at":"2023-12-04T19:28:24.552932Z"},"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg","error":[{"pipeline_execution_id":"pexec_cln2gm7e58clk12jrrtg","step_execution_id":"","pipeline":"slack.pipeline.list_channels","step":"list_channels","error":{"instance":"fperr_cln2gm7e58clk12jrrug","type":"error_internal","title":"Internal Error","status":500,"detail":"list_channels: Invalid function argument: Invalid value for \"lists\" parameter: list of string required.\n(/Users/cbruno/flowpipe/slack/pipelines/channel/list_channels.fp:35,32-43)\nUnsuitable value type: Unsuitable value: value must be known\n(/Users/cbruno/flowpipe/slack/pipelines/channel/list_channels.fp:34,20-31)\n"}}],"pipeline_output":null}}
graza-io commented 9 months ago

@cbruno10 / @vhadianto I set up a minimal reproduction:

pipeline "wrong" {
  title = "Wrong Param Type Testing"
  description = "https://github.com/turbot/pipe-fittings/issues/262"

  param "messages" {
    type = list(string)
    default = "just_a_string"
  }

  step "transform" "msgs" {
    for_each = { for s in param.messages : s => s }
    value = each.value
  }
}

Ran through the approaches, no passing of param:

❯ go run . pipeline run test.pipeline.wrong --host local
[flowpipe] Execution ID: exec_closkdva2uaardpcvurg
[wrong] Starting pipeline
[wrong] Internal Error: param: Iteration over non-iterable value: A value of type string cannot be used as the collection in a 'for' expression.
(/Users/graza/src/graza-io/flowpipe-mod-test/pipelines/wrong_type.fp:11,27-41)
[wrong] Failed 2ms

Passing an arg of wrong type:

❯ go run . pipeline run test.pipeline.wrong --host local --arg 'messages="hi"'
Error: Error executing pipeline - 400 Bad Request Bad Request (Bad Request: expected list type)

Passing correct arg type:

❯ go run . pipeline run test.pipeline.wrong --host local --arg 'messages=["hi","there"]'
[flowpipe] Execution ID: exec_closlcna2uaardpcvuvg
[wrong] Starting pipeline
[wrong.msgs[hi]] Starting transform
[wrong.msgs[there]] Starting transform
[wrong.msgs[hi]] Complete 1ms
[wrong.msgs[there]] Complete 1ms
[wrong] Complete 8ms exec_closlcna2uaardpcvuvg

Do these errors on first two suffice or do we need to some-how capture these and make a more friendly error?

Update: Local execution is same...

❯ go run . pipeline run test.pipeline.wrong --mod-location ~/src/graza-io/flowpipe-mod-test
[flowpipe] Execution ID: exec_clsoatsi016hbrc7ntv0
[wrong] Starting pipeline
[wrong] Internal Error: param: Iteration over non-iterable value: A value of type string cannot be used as the collection in a 'for' expression.
(/Users/graza/src/graza-io/flowpipe-mod-test/pipelines/wrong_type.fp:11,27-41)
[wrong] Failed 3ms
❯ go run . pipeline run test.pipeline.wrong --mod-location ~/src/graza-io/flowpipe-mod-test --arg 'messages="hi"'
Error: failed executing pipeline - Bad Request: Bad Request: expected list type