honeybadger 1.10.3 → 1.11.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +10 -0
  3. data/CHANGELOG.md +17 -10
  4. data/Gemfile.lock +1 -1
  5. data/features/rails.feature +6 -4
  6. data/features/step_definitions/rails_steps.rb +8 -0
  7. data/features/support/rails.rb +5 -0
  8. data/gemfiles/rack.gemfile.lock +1 -1
  9. data/gemfiles/rails2.3.gemfile.lock +1 -1
  10. data/gemfiles/rails3.0.gemfile.lock +1 -1
  11. data/gemfiles/rails3.1.gemfile.lock +1 -1
  12. data/gemfiles/rails3.2.gemfile.lock +1 -1
  13. data/gemfiles/rails4.gemfile.lock +1 -1
  14. data/gemfiles/rails4_cap3.gemfile +13 -0
  15. data/gemfiles/rails4_cap3.gemfile.lock +204 -0
  16. data/gemfiles/rake.gemfile.lock +1 -1
  17. data/gemfiles/sinatra.gemfile.lock +1 -1
  18. data/honeybadger.gemspec +7 -4
  19. data/lib/honeybadger.rb +14 -1
  20. data/lib/honeybadger/capistrano.rb +4 -45
  21. data/lib/honeybadger/capistrano/legacy.rb +45 -0
  22. data/lib/honeybadger/capistrano/tasks.rake +67 -0
  23. data/lib/honeybadger/configuration.rb +2 -2
  24. data/lib/honeybadger/monitor/worker.rb +1 -1
  25. data/lib/honeybadger/notice.rb +10 -1
  26. data/lib/honeybadger/rack.rb +1 -0
  27. data/lib/honeybadger/rails.rb +8 -0
  28. data/lib/honeybadger/railtie.rb +1 -7
  29. data/lib/honeybadger/stats.rb +1 -1
  30. data/lib/honeybadger/templates/{feedback_form.html.erb → feedback_form.erb} +12 -9
  31. data/lib/honeybadger/user_feedback.rb +47 -17
  32. data/lib/honeybadger_tasks.rb +3 -3
  33. data/lib/rails/generators/honeybadger/honeybadger_generator.rb +1 -2
  34. data/spec/honeybadger/capistrano_spec.rb +26 -23
  35. data/spec/honeybadger/configuration_spec.rb +25 -21
  36. data/spec/honeybadger/notice_spec.rb +30 -37
  37. data/spec/honeybadger/notifier_spec.rb +60 -4
  38. data/spec/honeybadger/rack_spec.rb +1 -0
  39. data/spec/honeybadger/user_feedback_spec.rb +29 -4
  40. data/spec/honeybadger_tasks_spec.rb +13 -4
  41. metadata +9 -6
  42. data/spec/honeybadger/stats_spec.rb +0 -57
data/honeybadger.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'honeybadger'
7
- s.version = '1.10.3'
8
- s.date = '2014-02-05'
7
+ s.version = '1.11.0.beta1'
8
+ s.date = '2014-01-17'
9
9
 
10
10
  s.summary = 'Error reports you can be happy about.'
11
11
  s.description = 'Make managing application errors a more pleasant experience.'
@@ -74,6 +74,8 @@ Gem::Specification.new do |s|
74
74
  gemfiles/rails3.2.gemfile.lock
75
75
  gemfiles/rails4.gemfile
76
76
  gemfiles/rails4.gemfile.lock
77
+ gemfiles/rails4_cap3.gemfile
78
+ gemfiles/rails4_cap3.gemfile.lock
77
79
  gemfiles/rake.gemfile
78
80
  gemfiles/rake.gemfile.lock
79
81
  gemfiles/sinatra.gemfile
@@ -89,6 +91,8 @@ Gem::Specification.new do |s|
89
91
  lib/honeybadger/array.rb
90
92
  lib/honeybadger/backtrace.rb
91
93
  lib/honeybadger/capistrano.rb
94
+ lib/honeybadger/capistrano/legacy.rb
95
+ lib/honeybadger/capistrano/tasks.rake
92
96
  lib/honeybadger/configuration.rb
93
97
  lib/honeybadger/monitor.rb
94
98
  lib/honeybadger/monitor/railtie.rb
@@ -107,7 +111,7 @@ Gem::Specification.new do |s|
107
111
  lib/honeybadger/shared_tasks.rb
108
112
  lib/honeybadger/stats.rb
109
113
  lib/honeybadger/tasks.rb
110
- lib/honeybadger/templates/feedback_form.html.erb
114
+ lib/honeybadger/templates/feedback_form.erb
111
115
  lib/honeybadger/user_feedback.rb
112
116
  lib/honeybadger/user_informer.rb
113
117
  lib/honeybadger_tasks.rb
@@ -127,7 +131,6 @@ Gem::Specification.new do |s|
127
131
  spec/honeybadger/rails/action_controller_spec.rb
128
132
  spec/honeybadger/rails_spec.rb
129
133
  spec/honeybadger/sender_spec.rb
130
- spec/honeybadger/stats_spec.rb
131
134
  spec/honeybadger/user_feedback_spec.rb
132
135
  spec/honeybadger/user_informer_spec.rb
133
136
  spec/honeybadger_tasks_spec.rb
data/lib/honeybadger.rb CHANGED
@@ -16,7 +16,7 @@ require 'honeybadger/user_feedback'
16
16
  require 'honeybadger/railtie' if defined?(Rails::Railtie)
17
17
 
18
18
  module Honeybadger
19
- VERSION = '1.10.3'
19
+ VERSION = '1.11.0.beta1'
20
20
  LOG_PREFIX = "** [Honeybadger] "
21
21
 
22
22
  HEADERS = {
@@ -90,6 +90,19 @@ module Honeybadger
90
90
  @configuration ||= Configuration.new
91
91
  end
92
92
 
93
+ # Internal: Contacts the Honeybadger service and configures features
94
+ #
95
+ # configuration - the Configuration object to use
96
+ #
97
+ # Returns Hash features on success, NilClass on failure
98
+ def ping(configuration)
99
+ if configuration.public?
100
+ if result = sender.ping({ :version => Honeybadger::VERSION, :framework => configuration.framework, :environment => configuration.environment_name, :hostname => configuration.hostname })
101
+ configuration.features = result['features'] if result['features']
102
+ end
103
+ end
104
+ end
105
+
93
106
  # Public: Sends an exception manually using this method, even when you are not in a controller.
94
107
  #
95
108
  # exception - The exception you want to notify Honeybadger about.
@@ -1,48 +1,7 @@
1
- # Defines deploy:notify_honeybadger which will send information about the deploy to Honeybadger.
2
1
  require 'capistrano'
3
2
 
4
- module Honeybadger
5
- module Capistrano
6
- def self.load_into(configuration)
7
- configuration.load do
8
- after "deploy", "honeybadger:deploy"
9
- after "deploy:migrations", "honeybadger:deploy"
10
-
11
- namespace :honeybadger do
12
- desc <<-DESC
13
- Notify Honeybadger of the deployment by running the notification on the REMOTE machine.
14
- - Run remotely so we use remote API keys, environment, etc.
15
- DESC
16
- task :deploy, :except => { :no_release => true } do
17
- rails_env = fetch(:rails_env, "production")
18
- honeybadger_env = fetch(:honeybadger_env, fetch(:rails_env, "production"))
19
- rake_task = fetch(:honeybadger_deploy_task, 'honeybadger:deploy')
20
- local_user = ENV['USER'] || ENV['USERNAME']
21
- executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, 'rake.bat') : fetch(:rake, 'rake')
22
- async_notify = fetch(:honeybadger_async_notify, false)
23
- directory = configuration.current_release
24
- notify_command = "cd #{directory};"
25
- notify_command << " nohup" if async_notify
26
- notify_command << " #{executable} RAILS_ENV=#{rails_env} #{rake_task} TO=#{honeybadger_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
27
- notify_command << " DRY_RUN=true" if dry_run
28
- notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
29
- notify_command << " >> /dev/null 2>&1 &" if async_notify
30
- logger.info "Notifying Honeybadger of Deploy (#{notify_command})"
31
- if configuration.dry_run
32
- logger.info "DRY RUN: Notification not actually run."
33
- else
34
- result = ""
35
- run(notify_command, :once => true, :pty => false) { |ch, stream, data| result << data }
36
- # TODO: Check if SSL is active on account via result content.
37
- end
38
- logger.info "Honeybadger Notification Complete."
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
45
-
46
- if Capistrano::Configuration.instance
47
- Honeybadger::Capistrano.load_into(Capistrano::Configuration.instance)
3
+ if defined?(Capistrano::Configuration.instance)
4
+ require 'honeybadger/capistrano/legacy'
5
+ else
6
+ load File.expand_path('../capistrano/tasks.rake', __FILE__)
48
7
  end
@@ -0,0 +1,45 @@
1
+ module Honeybadger
2
+ module Capistrano
3
+ def self.load_into(configuration)
4
+ configuration.load do
5
+ after "deploy", "honeybadger:deploy"
6
+ after "deploy:migrations", "honeybadger:deploy"
7
+
8
+ namespace :honeybadger do
9
+ desc <<-DESC
10
+ Notify Honeybadger of the deployment by running the notification on the REMOTE machine.
11
+ - Run remotely so we use remote API keys, environment, etc.
12
+ DESC
13
+ task :deploy, :except => { :no_release => true } do
14
+ rails_env = fetch(:rails_env, "production")
15
+ honeybadger_env = fetch(:honeybadger_env, fetch(:rails_env, "production"))
16
+ rake_task = fetch(:honeybadger_deploy_task, 'honeybadger:deploy')
17
+ local_user = ENV['USER'] || ENV['USERNAME']
18
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, 'rake.bat') : fetch(:rake, 'rake')
19
+ async_notify = fetch(:honeybadger_async_notify, false)
20
+ directory = configuration.current_release
21
+ notify_options = "cd #{directory};"
22
+ notify_options << " nohup" if async_notify
23
+ notify_options << " #{executable} RAILS_ENV=#{rails_env} #{rake_task} TO=#{honeybadger_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
24
+ notify_options << " DRY_RUN=true" if dry_run
25
+ notify_options << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
26
+ notify_options << " >> /dev/null 2>&1 &" if async_notify
27
+ logger.info "Notifying Honeybadger of Deploy (#{notify_options})"
28
+ if configuration.dry_run
29
+ logger.info "DRY RUN: Notification not actually run."
30
+ else
31
+ result = ""
32
+ run(notify_options, :once => true, :pty => false) { |ch, stream, data| result << data }
33
+ # TODO: Check if SSL is active on account via result content.
34
+ end
35
+ logger.info "Honeybadger Notification Complete."
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ if Capistrano::Configuration.instance
44
+ Honeybadger::Capistrano.load_into(Capistrano::Configuration.instance)
45
+ end
@@ -0,0 +1,67 @@
1
+ after 'deploy:finishing', 'honeybadger:deploy'
2
+
3
+ namespace :honeybadger do
4
+ def sshkit_outdated?
5
+ !::SSHKit.config.command_map.respond_to?(:prefix)
6
+ end
7
+
8
+ desc 'Notify Honeybadger of the deployment.'
9
+ task :deploy => :env do
10
+ next if sshkit_outdated?
11
+ if server = fetch(:honeybadger_server)
12
+ on server do |host|
13
+ info 'Notifying Honeybadger of deploy.'
14
+
15
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, :'rake.bat') : fetch(:rake, :rake)
16
+ rake_task = fetch(:honeybadger_deploy_task, 'honeybadger:deploy')
17
+
18
+ options = [rake_task]
19
+
20
+ if fetch(:honeybadger_async_notify, false)
21
+ ::SSHKit.config.command_map.prefix[:rake].push(:nohup)
22
+ options << '>> /dev/null 2>&1 &'
23
+ end
24
+
25
+ within release_path do
26
+ execute executable, options
27
+ end
28
+
29
+ info 'Honeybadger notification complete.'
30
+ end
31
+ end
32
+ end
33
+
34
+ desc 'Setup ENV for Honeybadger deploy rake task.'
35
+ task :env do
36
+ if sshkit_outdated?
37
+ run_locally do
38
+ warn 'Unable to notify Honeybadger: you are using an outdated version of SSHKIT. Please upgrade to >= 1.2.0.'
39
+ end
40
+ next
41
+ end
42
+
43
+ server = fetch(:honeybadger_server) do
44
+ s = primary(:app)
45
+ set(:honeybadger_server, s.select?({ :exclude => :no_release }) ? s : nil)
46
+ end
47
+
48
+ if server
49
+ on server do |host|
50
+ rails_env = fetch(:rails_env, "production")
51
+ honeybadger_env = fetch(:honeybadger_env, rails_env)
52
+ repository = fetch(:repo_url)
53
+ local_user = fetch(:honeybadger_user, ENV['USER'] || ENV['USERNAME'])
54
+ api_key = fetch(:honeybadger_api_key, ENV['HONEYBADGER_API_KEY'] || ENV['API_KEY'])
55
+ revision = fetch(:current_revision) do
56
+ within(repo_path) do
57
+ capture("cd #{repo_path} && git rev-parse --short HEAD")
58
+ end
59
+ end
60
+
61
+ env = ["RAILS_ENV=#{rails_env}", "TO=#{honeybadger_env}", "REVISION=#{revision}", "REPO=#{repository}", "USER=#{local_user}"]
62
+ env << "API_KEY=#{api_key}" if api_key
63
+ ::SSHKit.config.command_map.prefix[:rake].unshift(*env)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -261,9 +261,9 @@ module Honeybadger
261
261
 
262
262
  # Public: Determines if the notifier will send notices.
263
263
  #
264
- # Returns false if in a development environment, true otherwise.
264
+ # Returns true if allowed to talk to API, false otherwise.
265
265
  def public?
266
- !development_environments.include?(environment_name) && features['notices']
266
+ !development_environments.include?(environment_name)
267
267
  end
268
268
 
269
269
  # Public: Determines whether to send metrics
@@ -72,7 +72,7 @@ module Honeybadger
72
72
  end
73
73
  end.each_slice(@per_request) do |mm|
74
74
  begin
75
- @sender.send_metrics({ :metrics => mm.compact, :environment => Honeybadger.configuration.environment_name, :hostname => Honeybadger.configuration.hostname })
75
+ @sender.send_metrics({ :metrics => mm, :environment => Honeybadger.configuration.environment_name, :hostname => Honeybadger.configuration.hostname })
76
76
  rescue Exception => e
77
77
  log(:error, "[Honeybadger::Monitor::Worker#send_metrics] Failed to send #{mm.count} metrics: #{e.class} - #{e.message}\nBacktrace:\n#{e.backtrace.join("\n\t")}")
78
78
  end
@@ -305,7 +305,7 @@ module Honeybadger
305
305
  return nil unless url =~ /\S/
306
306
 
307
307
  url = url.dup
308
- url.scan(/&([^=]+)=([^&]+)/).each do |m|
308
+ url.scan(/(?:^|&|\?)([^=?&]+)=([^&]+)/).each do |m|
309
309
  next unless filter_key?(m[0])
310
310
  url.gsub!(/#{m[1]}/, '[FILTERED]')
311
311
  end
@@ -321,6 +321,7 @@ module Honeybadger
321
321
  if cgi_data
322
322
  clean_unserializable_data_from(:cgi_data)
323
323
  filter(cgi_data)
324
+ filter_cgi_data_params(cgi_data)
324
325
  end
325
326
  if session_data
326
327
  clean_unserializable_data_from(:session_data)
@@ -328,9 +329,17 @@ module Honeybadger
328
329
  end
329
330
  end
330
331
 
332
+ def filter_cgi_data_params(cgi_data)
333
+ cgi_data.each_pair do |key, value|
334
+ next unless value.kind_of?(String) && key =~ /\A[A-Z_]+\Z/
335
+ cgi_data[key] = filter_url(value)
336
+ end
337
+ end
338
+
331
339
  def clean_rack_request_data
332
340
  if cgi_data
333
341
  cgi_data.delete("rack.request.form_vars")
342
+ cgi_data.delete("rack.request.query_string")
334
343
  end
335
344
  end
336
345
 
@@ -22,6 +22,7 @@ module Honeybadger
22
22
  class Rack
23
23
  def initialize(app)
24
24
  @app = app
25
+ Honeybadger.configuration.framework = "Rack: #{::Rack.release}"
25
26
  end
26
27
 
27
28
  def ignored_user_agent?(env)
@@ -21,6 +21,8 @@ module Honeybadger
21
21
  Honeybadger::Rack
22
22
  ::Rails.configuration.middleware.insert_after 'Rack::Lock',
23
23
  Honeybadger::UserInformer
24
+ ::Rails.configuration.middleware.insert_after Honeybadger::UserInformer,
25
+ Honeybadger::UserFeedback
24
26
  end
25
27
 
26
28
  Honeybadger.configure(true) do |config|
@@ -29,6 +31,12 @@ module Honeybadger
29
31
  config.project_root = defined?(::Rails.root) && ::Rails.root || defined?(RAILS_ROOT) && RAILS_ROOT
30
32
  config.framework = defined?(::Rails.version) && "Rails: #{::Rails.version}" || defined?(::Rails::VERSION::STRING) && "Rails: #{::Rails::VERSION::STRING}"
31
33
  end
34
+
35
+ if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:after_initialize)
36
+ ::Rails.configuration.after_initialize do
37
+ Honeybadger.ping(Honeybadger.configuration)
38
+ end
39
+ end
32
40
  end
33
41
  end
34
42
  end
@@ -44,13 +44,7 @@ module Honeybadger
44
44
  ::ActionDispatch::ShowExceptions.send(:include,Honeybadger::Rails::Middleware::ExceptionsCatcher)
45
45
  end
46
46
 
47
- if Honeybadger.configuration.public?
48
- if result = Honeybadger.sender.ping({ :version => Honeybadger::VERSION, :framework => Honeybadger.configuration.framework, :environment => Honeybadger.configuration.environment_name, :hostname => Honeybadger.configuration.hostname })
49
- Honeybadger.configure(true) do |config|
50
- config.features = result['features'] if result['features']
51
- end
52
- end
53
- end
47
+ Honeybadger.ping(Honeybadger.configuration)
54
48
  end
55
49
  end
56
50
  end
@@ -12,7 +12,7 @@ module Honeybadger
12
12
  def memory
13
13
  out = {}
14
14
  if HAS_MEM
15
- out[:total], out[:free], out[:buffers], out[:cached] = IO.readlines("/proc/meminfo")[0..4].map { |l| l =~ /^.*?\: +(.*?) kB$/; ($1.to_i / 1024.0).to_f }
15
+ out[:total], out[:free], out[:buffers], out[:cached] = IO.readlines("/proc/meminfo")[0..4].map { |l| l =~ /^.*?\: +(.*?) kB$/; $1.to_i / 1024.0 }
16
16
  out[:free_total] = out[:free] + out[:buffers] + out[:cached]
17
17
  end
18
18
  out
@@ -6,6 +6,7 @@
6
6
  #honeybadger_feedback_comment { height: 10em; }
7
7
  #honeybadger_feedback_submit { height: 1em; }
8
8
  #honeybadger_feedback_form .honeybadger-feedback-phone { display: none; }
9
+ #honeybadger_feedback_link { font-size: 90%; }
9
10
  </style>
10
11
 
11
12
  <script>
@@ -22,7 +23,7 @@ function honeybadgerFeedbackResponse(data) {
22
23
  if (data['error']) {
23
24
  message = data['error'];
24
25
  } else {
25
- message = "An unknown error occurred. Please try again.";
26
+ message = 'An unknown error occurred. Please try again.';
26
27
  }
27
28
 
28
29
  alert(message);
@@ -47,36 +48,38 @@ function sendHoneybadgerFeedback() {
47
48
  </script>
48
49
 
49
50
  <div id="honeybadger_feedback_success" style="display:none;">
50
- <p><strong>Thanks for the feedback!</strong></p>
51
+ <p><strong><%= I18n.t('honeybadger.feedback.thanks', :default => 'Thanks for the feedback!') %></strong></p>
51
52
  </div>
52
53
 
53
54
  <form action="<%= action %>" method="POST" id="honeybadger_feedback_form" onsubmit="return sendHoneybadgerFeedback();">
54
55
  <input type="hidden" name="token" id="honeybadger_feedback_token" value="<%= error_id %>">
55
56
 
56
- <h2>Care to help us fix this?</h2>
57
- <p>Any information you can provide will help our technical team get to the bottom of this issue.</p>
57
+ <h2><%= I18n.t('honeybadger.feedback.heading', :default => 'Care to help us fix this?') %></h2>
58
+ <p><%= I18n.t('honeybadger.feedback.explanation', :default => 'Any information you can provide will help our technical team get to the bottom of this issue.') %></p>
58
59
 
59
60
  <p class="honeybadger-feedback-name">
60
- <label for="honeybadger_feedback_name">Your name</label><br>
61
+ <label for="honeybadger_feedback_name"><%= I18n.t('honeybadger.feedback.labels.name', :default => 'Your name') %></label><br>
61
62
  <input type="text" name="name" id="honeybadger_feedback_name" size="60">
62
63
  </p>
63
64
 
64
65
  <p class="honeybadger-feedback-phone">
65
- <label for="honeybadger_feedback_phone">Your phone number</label><br>
66
+ <label for="honeybadger_feedback_phone"><%= I18n.t('honeybadger.feedback.labels.phone', :default => 'Your phone number') %></label><br>
66
67
  <input type="text" name="phone" id="honeybadger_feedback_phone" size="60">
67
68
  </p>
68
69
 
69
70
  <p class="honeybadger-feedback-email">
70
- <label for="honeybadger_feedback_email">Your email address</label><br>
71
+ <label for="honeybadger_feedback_email"><%= I18n.t('honeybadger.feedback.labels.email', :default => 'Your email address') %></label><br>
71
72
  <input type="email" name="email" id="honeybadger_feedback_email" size="60">
72
73
  </p>
73
74
 
74
75
  <p class="honeybadger-feedback-comment">
75
- <label for="honeybadger_feedback_comment">Comment (required)</label><br>
76
+ <label for="honeybadger_feedback_comment"><%= I18n.t('honeybadger.feedback.labels.comment', :default => 'Comment (required)') %></label><br>
76
77
  <textarea name="comment" id="honeybadger_feedback_comment" cols="50" rows="6" required></textarea>
77
78
  </p>
78
79
 
79
80
  <p class="honeybadger-feedback-submit">
80
- <input type="submit" id="honeybadger_feedback_submit" value="Send">
81
+ <input type="submit" id="honeybadger_feedback_submit" value="<%= I18n.t('honeybadger.feedback.submit', :default => 'Send') %>">
81
82
  </p>
82
83
  </form>
84
+
85
+ <p><a id="honeybadger_feedback_link" href="https://www.honeybadger.io/" target="_blank" title="Exception, uptime, and performance monitoring for Ruby.">Powered by Honeybadger</a></p>
@@ -1,16 +1,47 @@
1
1
  require 'erb'
2
2
  require 'uri'
3
3
 
4
+ begin
5
+ require 'i18n'
6
+ rescue LoadError
7
+ module Honeybadger
8
+ module I18n
9
+ def self.t(key, options={})
10
+ options[:default]
11
+ end
12
+ end
13
+ end
14
+ end
15
+
4
16
  module Honeybadger
5
17
  class UserFeedback
6
- TEMPLATE = File.read(File.expand_path('../templates/feedback_form.html.erb', __FILE__)).freeze
7
-
8
18
  def initialize(app)
9
19
  @app = app
10
20
  end
11
21
 
22
+ def call(env)
23
+ status, headers, body = @app.call(env)
24
+ if enabled? && env['honeybadger.error_id'] && form = render_form(env['honeybadger.error_id'])
25
+ new_body = []
26
+ body.each do |chunk|
27
+ new_body << chunk.gsub("<!-- HONEYBADGER FEEDBACK -->", form)
28
+ end
29
+ body.close if body.respond_to?(:close)
30
+ headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
31
+ body = new_body
32
+ end
33
+ [status, headers, body]
34
+ end
35
+
36
+ def config
37
+ Honeybadger.configuration
38
+ end
39
+
40
+ def enabled?
41
+ config.feedback && config.features['feedback']
42
+ end
43
+
12
44
  def action
13
- config = Honeybadger.configuration
14
45
  URI.parse("#{config.protocol}://#{config.host}:#{config.port}/v1/feedback/").to_s
15
46
  rescue URI::InvalidURIError
16
47
  nil
@@ -18,25 +49,24 @@ module Honeybadger
18
49
 
19
50
  def render_form(error_id, action = action)
20
51
  return unless action
21
- ERB.new(TEMPLATE).result(binding)
52
+ ERB.new(@template ||= File.read(template_file)).result(binding)
22
53
  end
23
54
 
24
- def enabled?
25
- Honeybadger.configuration.feedback && Honeybadger.configuration.features['feedback']
55
+ def custom_template_file
56
+ @custom_template_file ||= config.project_root &&
57
+ File.join(config.project_root, 'lib', 'honeybadger', 'templates', 'feedback_form.erb')
26
58
  end
27
59
 
28
- def call(env)
29
- status, headers, body = @app.call(env)
30
- if enabled? && env['honeybadger.error_id'] && form = render_form(env['honeybadger.error_id'])
31
- new_body = []
32
- body.each do |chunk|
33
- new_body << chunk.gsub("<!-- HONEYBADGER FEEDBACK -->", form)
34
- end
35
- body.close if body.respond_to?(:close)
36
- headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
37
- body = new_body
60
+ def custom_template_file?
61
+ custom_template_file && File.exists?(custom_template_file)
62
+ end
63
+
64
+ def template_file
65
+ if custom_template_file?
66
+ custom_template_file
67
+ else
68
+ File.expand_path('../templates/feedback_form.erb', __FILE__)
38
69
  end
39
- [status, headers, body]
40
70
  end
41
71
  end
42
72
  end