Jira (BOLT-1366) Allow plans to return uniform Type, including on error

5 views
Skip to first unread message

Reid Vandewiele (JIRA)

unread,
Jun 6, 2019, 1:05:03 PM6/6/19
to puppe...@googlegroups.com
Reid Vandewiele updated an issue
 
Puppet Task Runner / Improvement BOLT-1366
Allow plans to return uniform Type, including on error
Change By: Reid Vandewiele
Summary: Overhaul user experience handling plan errors Allow plans to return uniform Type, including on error
Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Reid Vandewiele (JIRA)

unread,
Jun 6, 2019, 1:12:06 PM6/6/19
to puppe...@googlegroups.com
Reid Vandewiele updated an issue
It isn't possible today for a plan author to formally signal to callers that the plan failed (surfacing an error  without requiring the caller to provide distinct (and not bound by convention) code paths for "ok" vs. "error". E.g.

{code}
$results = case ($plan_result = run_plan('mymodule::myplan',
  '_catch_errors' => true,
)) {
  Error:   { $plan_result.details['result_set'] }
  default: { $plan_result }
}
{code}

Ideally, a caller should be able to expect a consistent return type regardless of whether or not the plan failed; just like a caller can always expect an object of type ResultSet to be returned from {{run_task}}.

Allow for a moment that a plan _always_ returns an object of type PlanResult. If this is true, we can generalize success/failure based on {{$pr.ok}}, just as ResultSet handling can be based on {{$rs.ok}}. If a PlanResult is not ok (it failed), we can generalize access to the error raised via e.g. {{$pr.error}}. The PlanResult object can define a standard interface to data returned by a plan, such as defining a {{.value}} method, and the index method ({{.[]}}) for easy access to returned data keys.

A caller could then simplify their code to e.g.

{code}
$result = run_plan('mymodule::myplan',
  _catch_errors => true,
)

run_task('mymodule::next_step, $result.value.ok_set)
{code}
OR
{code}
$result['summary']
{code}
OR
{code}
if !$result.ok {
  # handle it
}
{code}

...etc., depending on what the plan author chooses to return.

Being able to rely on the datatype returned by {{run_plan}} greatly simplifies how plan authors can call and deal with the results from running other plans.


One way of doing this might be to create a new type, PlanResult, which akin to ResultSet would come with a standard set of methods to interact with it. We could additionally define PlanResult::Error, which is still a PlanResult, but adds a {{.error}} method to access an included Error object, and would be compatible with code like {{case $result \{ Error: \{ ... \} \}​}}.

We could extend {{fail_plan}} to return a PlanResult::Error, if given a PlanResult return value and an Error. Plan authors could then choose to create well-formed plans in an opt-in way.

If we didn't have to deal with existing plans I'd say just always return a PlanResult, with a little more automation around it and less effort from the plan author. Maybe it's a better enough experience to make a change in 2.0.
Reply all
Reply to author
Forward
0 new messages