braintree / runbook

A framework for gradual system automation
MIT License
734 stars 43 forks source link

rescue from command Exception #38

Open endorama opened 4 years ago

endorama commented 4 years ago

Hello, I'm having a hard time trying to rescue a failed command execution in a meaningful way.

Excerpt from my code:

  section "helm chart" do
    step "Check Helm Chart exists" do
      ruby_command do 
        begin
          command "gsutil ls \"gs://a-helm-repository-bucket/#{app_name}-#{chart_version}.tgz\""
        rescue SSHKit::Command::Failed => e
          puts "Failed", e.inspect
        rescue SSHKit::Runner::ExecuteError => e
          puts "ExecuteError", e.inspect
        rescue => e
          puts "generic exception", e.inspect
        end
      end

      confirm "Does the Helm Chart exists?"
    end
  end

The goal of this snippet is to check if a GCP Cloud Storage Bucket Object for a Helm Chart is present, given an application name and a version (taken from user input).

Unfortunately though, I'm not able to rescue the exception in any meaningful way. I tried using raise_on_non_zero_exit but the effect is not what I'd want to achieve.

I'd like to be able to nicely handle known exceptions from this command, by inspecting the exception message and taking appropriate action. As I'm within a ruby_command I was expecting this to work (it should in any case probably?).

Is this even possible? If yes, how could I achieve the expected result? If not, any viable workaround?

Thanks!

abMatGit commented 3 years ago

It seems like the goto solution has been to append || true to commands so that it always returns an exit code of 0. https://github.com/braintree/runbook/issues/36

Personally I agree though -- this solution isn't good enough if you need to fork your runbook behaviour depending on certain steps.

Check if file is present --> exit 1 --> create the file exit 0 --> use said file

This is the code I use for that:

capture "file detect #{filename} && echo 'SUCCESS' || echo 'FAILURE'", into: :existing_file
      ruby_command do
        next if @existing_file == 'SUCCESS'

        command 'create file'
      end

I don't think we can do better than a true or false. If you want to get fancier you might need to do more bash which undermines the point of having a ruby runbook handler.

endorama commented 3 years ago

Thanks for the suggestion. I'll leave this open to see if there is other feedback but the workaround makes sense.