honeybadger 1.10.3 → 1.11.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Appraisals +10 -0
- data/CHANGELOG.md +17 -10
- data/Gemfile.lock +1 -1
- data/features/rails.feature +6 -4
- data/features/step_definitions/rails_steps.rb +8 -0
- data/features/support/rails.rb +5 -0
- data/gemfiles/rack.gemfile.lock +1 -1
- data/gemfiles/rails2.3.gemfile.lock +1 -1
- data/gemfiles/rails3.0.gemfile.lock +1 -1
- data/gemfiles/rails3.1.gemfile.lock +1 -1
- data/gemfiles/rails3.2.gemfile.lock +1 -1
- data/gemfiles/rails4.gemfile.lock +1 -1
- data/gemfiles/rails4_cap3.gemfile +13 -0
- data/gemfiles/rails4_cap3.gemfile.lock +204 -0
- data/gemfiles/rake.gemfile.lock +1 -1
- data/gemfiles/sinatra.gemfile.lock +1 -1
- data/honeybadger.gemspec +7 -4
- data/lib/honeybadger.rb +14 -1
- data/lib/honeybadger/capistrano.rb +4 -45
- data/lib/honeybadger/capistrano/legacy.rb +45 -0
- data/lib/honeybadger/capistrano/tasks.rake +67 -0
- data/lib/honeybadger/configuration.rb +2 -2
- data/lib/honeybadger/monitor/worker.rb +1 -1
- data/lib/honeybadger/notice.rb +10 -1
- data/lib/honeybadger/rack.rb +1 -0
- data/lib/honeybadger/rails.rb +8 -0
- data/lib/honeybadger/railtie.rb +1 -7
- data/lib/honeybadger/stats.rb +1 -1
- data/lib/honeybadger/templates/{feedback_form.html.erb → feedback_form.erb} +12 -9
- data/lib/honeybadger/user_feedback.rb +47 -17
- data/lib/honeybadger_tasks.rb +3 -3
- data/lib/rails/generators/honeybadger/honeybadger_generator.rb +1 -2
- data/spec/honeybadger/capistrano_spec.rb +26 -23
- data/spec/honeybadger/configuration_spec.rb +25 -21
- data/spec/honeybadger/notice_spec.rb +30 -37
- data/spec/honeybadger/notifier_spec.rb +60 -4
- data/spec/honeybadger/rack_spec.rb +1 -0
- data/spec/honeybadger/user_feedback_spec.rb +29 -4
- data/spec/honeybadger_tasks_spec.rb +13 -4
- metadata +9 -6
- 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.
|
8
|
-
s.date = '2014-
|
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.
|
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.
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
264
|
+
# Returns true if allowed to talk to API, false otherwise.
|
265
265
|
def public?
|
266
|
-
!development_environments.include?(environment_name)
|
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
|
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
|
data/lib/honeybadger/notice.rb
CHANGED
@@ -305,7 +305,7 @@ module Honeybadger
|
|
305
305
|
return nil unless url =~ /\S/
|
306
306
|
|
307
307
|
url = url.dup
|
308
|
-
url.scan(
|
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
|
|
data/lib/honeybadger/rack.rb
CHANGED
data/lib/honeybadger/rails.rb
CHANGED
@@ -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
|
data/lib/honeybadger/railtie.rb
CHANGED
@@ -44,13 +44,7 @@ module Honeybadger
|
|
44
44
|
::ActionDispatch::ShowExceptions.send(:include,Honeybadger::Rails::Middleware::ExceptionsCatcher)
|
45
45
|
end
|
46
46
|
|
47
|
-
|
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
|
data/lib/honeybadger/stats.rb
CHANGED
@@ -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$/;
|
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 =
|
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
|
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
|
57
|
-
<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"
|
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"
|
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"
|
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"
|
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(
|
52
|
+
ERB.new(@template ||= File.read(template_file)).result(binding)
|
22
53
|
end
|
23
54
|
|
24
|
-
def
|
25
|
-
|
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
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|