class ChefCore::Actions::ConvergeTarget::CCRFailureMapper

This converts chef client run failures to human-friendly exceptions with detail and remediation steps based on the failure type.

Attributes

params[R]

Public Class Methods

new(exception, params) click to toggle source
# File lib/chef_core/actions/converge_target/ccr_failure_mapper.rb, line 32
def initialize(exception, params)
  @params = params
  @cause_line = exception
end

Public Instance Methods

exception_args_from_cause() click to toggle source

Ideally we will write a custom handler to package up data we care about and present it more directly docs.chef.io/handlers.html For now, we'll just match the most common failures based on their messages.

# File lib/chef_core/actions/converge_target/ccr_failure_mapper.rb, line 55
def exception_args_from_cause
  # Ordering is important below.  Some earlier tests are more detailed
  # cases of things that will match more general tests further down.
  case @cause_line
  when /.*had an error:(.*:)\s+(.*$)/
    # Some invalid property value cases, among others.
    ["CHEFCCR002", $2]
  when /.*Chef::Exceptions::ValidationFailed:\s+Option action must be equal to one of:\s+(.*)!\s+You passed :(.*)\./
    # Invalid action - specialization of invalid property value, below
    ["CHEFCCR003", $2, $1]
  when /.*Chef::Exceptions::ValidationFailed:\s+(.*)/
    # Invalid resource property value
    ["CHEFCCR004", $1]
  when /.*NameError: undefined local variable or method `(.+)' for cookbook.+/
    # Invalid resource type in most cases
    ["CHEFCCR005", $1]
  when /.*NoMethodError: undefined method `(.+)' for cookbook.+/
    # Invalid resource type in most cases
    ["CHEFCCR005", $1]
  when /.*undefined method `(.*)' for Chef::Resource::(.+)::/
    # If we can get a resource name show that instead of the class name
    # TODO - for the best experience, we could instantiate the resource in invoke resource.name
    ["CHEFCCR006", $1, $2]
  when /.*undefined method `(.*)' for (.+)/
    # TODO - we started showing the class name instead of hte resource name.
    # name, which is confusing -
    # 'blah' is not a property of 'Chef::Resource::User::LinuxUser'.
    #

    ["CHEFCCR006", $1, $2]

    # Below would catch the general form of most errors, but the
    # message itself in those lines is not generally aligned
    # with the UX we want to provide.
    # when /.*Exception|Error.*:\s+(.*)/
  else
    nil
  end
end
raise_mapped_exception!() click to toggle source
# File lib/chef_core/actions/converge_target/ccr_failure_mapper.rb, line 37
def raise_mapped_exception!
  if @cause_line.nil?
    raise RemoteChefRunFailedToResolveError.new(params[:failed_report_path])
  else
    errid, *args = exception_args_from_cause
    if errid.nil?
      raise RemoteChefClientRunFailedUnknownReason.new
    else
      raise RemoteChefClientRunFailed.new(errid, *args)
    end

  end
end