Class: PraiseImpl

Inherits:
Object
  • Object
show all
Defined in:
lib/praise.rb

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (PraiseImpl) initialize(ignored_path, enabled = true, outputter = -> level, message { $stderr.puts message })

A new instance of PraiseImpl

Examples:

initialization

Praise = PraiseImpl.
    new(File.join(root, Katello.early_config.praise.ignored_path),
        -> level, message { Logging.logger['praise'].add Logging.level_num(level), message })

Parameters:

  • outputter (Proc) (defaults to: -> level, message { $stderr.puts message })

    a proc which ouputs/logs messages

  • enabled (true, false) (defaults to: true)
  • ignored_path (String)

    path to a yaml file with rules for ignored exceptions



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/praise.rb', line 15

def initialize(ignored_path, enabled = true, outputter = -> level, message { $stderr.puts message })
  @outputter = outputter
  unless File.exist? ignored_path
    log :info, "creating #{ignored_path} file"
    File.open(ignored_path, 'w') { |f| f.write [].to_yaml }
  end
  @ignored_path = ignored_path
  @enabled      = false
  reload

  self.enabled = enabled
end

Instance Attribute Details

- (Object) enabled

Returns the value of attribute enabled



6
7
8
# File 'lib/praise.rb', line 6

def enabled
  @enabled
end

Instance Method Details

- (Object) add_rule(rule)

This will add a rule for exception ignoring. Can be called at runtime, next exception occurrence will be ignored.

Parameters:

  • rule (Hash{:class, :message, :line => Regexp, String})

    for ignoring an exception



35
36
37
38
39
# File 'lib/praise.rb', line 35

def add_rule(rule)
  ignored = File.open(@ignored_path, 'r') { |f| YAML.load(f.read) }
  File.open(@ignored_path, 'w') { |f| f.write(ignored.push(rule).to_yaml) }
  reload
end

- (true, false) ignore?(exception_instance, message, risen_at)

Should the exception ignored?

Returns:

  • (true, false)

    should the exception ignored?



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/praise.rb', line 53

def ignore?(exception_instance, message, risen_at)
  ignored.any? do |hash|
    hash.all? do |type, condition|
      case type
      when :class
        exception_instance.class.to_s == condition
      when :message
        message =~ condition
      when :line
        risen_at =~ condition
      end
    end
  end.tap do |ignore|
    log :debug, "ignored exception: (#{exception_instance.class}) #{message}\n    #{risen_at}" if ignore
  end
end

- (Array<Hash{:class, :message, :line => Regexp, String}>) ignored

Rules for exception ignoring

Returns:

  • (Array<Hash{:class, :message, :line => Regexp, String}>)

    rules for exception ignoring



29
30
31
# File 'lib/praise.rb', line 29

def ignored
  @ignored ||= YAML.load File.read(@ignored_path)
end

- (Object) install (private)



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/praise.rb', line 83

def install
  log :info, 'installing praise'
  praise = self
  Kernel.module_eval do
    define_method :_original_raise, Kernel.instance_method(:raise)

    remove_method :raise
    Thread.current[:__pry_in_rescue__] = false

    define_method :raise do |*args|
      begin
        message             = args.find { |o| o.kind_of? String }
        backtrace           = args.find { |o| o.kind_of? Array }
        exception_generator = args.find { |o| ![message, backtrace].include? o } || RuntimeError
        #noinspection RubyArgCount
        exception           = message ? exception_generator.exception(message) : exception_generator.exception
        message             ||= exception.message
        risen_at            = caller(1).first

        unless Thread.current[:__pry_in_rescue__] || praise.ignore?(exception, message, risen_at)
          Thread.current[:__pry_in_rescue__] = true
          binding.pry
        end

        _original_raise *args
      ensure
        Thread.current[:__pry_in_rescue__] = false
      end
    end

    # TODO alias fail as well, currently does not work with thin
    #remove_method :fail
    #alias_method :fail, :raise
  end
  self
end

- (Object) log(level, message) (private)

log message on level



79
80
81
# File 'lib/praise.rb', line 79

def log(level, message)
  @outputter.call(level, message)
end

- (Object) reload (private)

reload ignored form file



73
74
75
76
# File 'lib/praise.rb', line 73

def reload
  @ignored = nil
  ignored
end

- (Object) uninstall (private)



120
121
122
123
124
# File 'lib/praise.rb', line 120

def uninstall
  Kernel.module_eval do
    define_method :raise, Kernel.instance_method(:_original_raise)
  end
end