Module: Honeybadger::CLI::Helpers

Included in:
Heroku, Main
Defined in:
lib/honeybadger/cli/helpers.rb

Instance Method Summary collapse

Instance Method Details

#load_rails(opts = {}) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/honeybadger/cli/helpers.rb', line 10

def load_rails(opts = {})
  begin
    require 'honeybadger/init/rails'
    if ::Rails::VERSION::MAJOR >= 3
      say("Detected Rails #{::Rails::VERSION::STRING}") if opts[:verbose]
    else
      say("Error: Rails #{::Rails::VERSION::STRING} is unsupported.", :red)
      exit(1)
    end
  rescue LoadError
    say("Rails was not detected, loading standalone.") if opts[:verbose]
    return @rails = false
  rescue StandardError => e
    say("Error while detecting Rails: #{e.class} -- #{e.message}", :red)
    exit(1)
  end

  begin
    require File.expand_path('config/application')
  rescue LoadError
    say('Error: could not load Rails application. Please ensure you run this command from your project root.', :red)
    exit(1)
  end

  @rails = true
end

#load_rails_env(opts = {}) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/honeybadger/cli/helpers.rb', line 37

def load_rails_env(opts = {})
  return false unless rails?(opts)

  puts('Loading Rails environment') if opts[:verbose]
  ::Rails.application.require_environment!

  true
end

#rails?(opts = {}) ⇒ Boolean

Returns:

  • (Boolean)


6
7
8
# File 'lib/honeybadger/cli/helpers.rb', line 6

def rails?(opts = {})
  @rails ||= load_rails(opts)
end

#rails_framework_optsObject



46
47
48
49
50
51
52
53
54
55
# File 'lib/honeybadger/cli/helpers.rb', line 46

def rails_framework_opts
  return {} unless defined?(::Rails)

  {
    :root           => ::Rails.root,
    :env            => ::Rails.env,
    :'config.path'  => ::Rails.root.join('config', 'honeybadger.yml'),
    :framework      => :rails
  }
end

#rails_test(verbose = true) ⇒ Object



76
77
78
79
80
81
82
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/honeybadger/cli/helpers.rb', line 76

def rails_test(verbose = true)
  if verbose
    ::Rails.logger = if defined?(::ActiveSupport::TaggedLogging)
                       ::ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
                     else
                       Logger.new(STDOUT)
                     end
    ::Rails.logger.level = Logger::INFO
  end

  # Suppress error logging in Rails' exception handling middleware. Rails 3.0
  # uses ActionDispatch::ShowExceptions to rescue/show exceptions, but does
  # not log anything but application trace. Rails 3.2 now falls back to
  # logging the framework trace (moved to ActionDispatch::DebugExceptions),
  # which caused cluttered output while running the test task.
  defined?(::ActionDispatch::DebugExceptions) and
    ::ActionDispatch::DebugExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }
  defined?(::ActionDispatch::ShowExceptions) and
  ::ActionDispatch::ShowExceptions.class_eval { def logger(*args) ; @logger ||= Logger.new('/dev/null') ; end }

  # Detect and disable the better_errors gem
  if defined?(::BetterErrors::Middleware)
    say('Better Errors detected: temporarily disabling middleware.', :yellow)
    ::BetterErrors::Middleware.class_eval { def call(env) @app.call(env); end }
  end

  begin
    require './app/controllers/application_controller'
  rescue LoadError
    nil
  end

  unless defined?(::ApplicationController)
    say('Error: No ApplicationController found.', :red)
    return false
  end

  say('Setting up the Controller.')
  eval(<<-CONTROLLER)
  class Honeybadger::TestController < ApplicationController
    # This is to bypass any filters that may prevent access to the action.
    prepend_before_filter :test_honeybadger

    def test_honeybadger
      puts "Raising '#{test_exception_class.name}' to simulate application failure."
      raise #{test_exception_class}.new, 'Testing honeybadger via "honeybadger test", it works.'
    end

    # Ensure we actually have an action to go to.
    def verify; end
  end
  CONTROLLER

  ::Rails.application.routes.tap do |r|
    # RouteSet#disable_clear_and_finalize prevents existing routes from
    # being cleared. We'll set it back to the original value when we're
    # done so not to mess with Rails state.
    d = r.disable_clear_and_finalize
    begin
      r.disable_clear_and_finalize = true
      r.clear!
      r.draw do
        match 'verify' => 'honeybadger/test#verify', :as => 'verify', :via => :get
      end
      ::Rails.application.routes_reloader.paths.each{ |path| load(path) }
      ::ActiveSupport.on_load(:action_controller) { r.finalize! }
    ensure
      r.disable_clear_and_finalize = d
    end
  end

  say('Processing request.')

  ssl = defined?(::Rails.configuration.force_ssl) && ::Rails.configuration.force_ssl
  env = ::Rack::MockRequest.env_for("http#{ ssl ? 's' : nil }://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')

  ::Rails.application.call(env)
end

#send_test(verbose = true) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/honeybadger/cli/helpers.rb', line 64

def send_test(verbose = true)
  if defined?(::Rails)
    rails_test(verbose)
  else
    standalone_test
  end
end

#standalone_testObject



72
73
74
# File 'lib/honeybadger/cli/helpers.rb', line 72

def standalone_test
  Honeybadger.notify(test_exception_class.new('Testing honeybadger via "honeybadger test". If you can see this, it works.'))
end

#test_exception_classObject



57
58
59
60
61
62
# File 'lib/honeybadger/cli/helpers.rb', line 57

def test_exception_class
  exception_name = ENV['EXCEPTION'] || 'HoneybadgerTestingException'
  Object.const_get(exception_name)
rescue
  Object.const_set(exception_name, Class.new(Exception))
end