code: func Resolve(ctx context.Context, task *api.Task, executor Executor) (Controller, *api.TaskStatus, error) {
  	status := task.Status.Copy()
  
  	defer func() {
  		logStateChange(ctx, task.DesiredState, task.Status.State, status.State)
  	}()
  
  	ctlr, err := executor.Controller(task)
  
  	// depending on the tasks state, a failed controller resolution has varying
  	// impact. The following expresses that impact.
  	if err != nil {
  		status.Message = "resolving controller failed"
  		status.Err = err.Error()
  		// before the task has been started, we consider it a rejection.
  		// if task is running, consider the task has failed
  		// otherwise keep the existing state
  		if task.Status.State < api.TaskStateStarting {
  			status.State = api.TaskStateRejected
  		} else if task.Status.State <= api.TaskStateRunning {
  			status.State = api.TaskStateFailed
  		}
  	} else if task.Status.State < api.TaskStateAccepted {
  		// we always want to proceed to accepted when we resolve the controller
  		status.Message = "accepted"
  		status.State = api.TaskStateAccepted
  		status.Err = ""
  	}
  
  	return ctlr, status, err
  }
docs: // Resolve attempts to get a controller from the executor and reports the
  // correct status depending on the tasks current state according to the result.
  //
  // Unlike Do, if an error is returned, the status should still be reported. The
  // error merely reports the failure at getting the controller.