exception_handling 2.2.1 → 2.3.0.pre.1
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -0
- data/Gemfile +7 -6
- data/Gemfile.lock +26 -23
- data/README.md +0 -1
- data/Rakefile +4 -4
- data/config/exception_filters.yml +2 -3
- data/exception_handling.gemspec +12 -10
- data/lib/exception_handling/exception_catalog.rb +5 -4
- data/lib/exception_handling/exception_description.rb +28 -28
- data/lib/exception_handling/exception_info.rb +80 -72
- data/lib/exception_handling/honeybadger_callbacks.rb +41 -24
- data/lib/exception_handling/log_stub_error.rb +10 -8
- data/lib/exception_handling/mailer.rb +27 -48
- data/lib/exception_handling/methods.rb +15 -11
- data/lib/exception_handling/sensu.rb +7 -5
- data/lib/exception_handling/testing.rb +21 -19
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +105 -200
- data/test/helpers/controller_helpers.rb +3 -1
- data/test/helpers/exception_helpers.rb +9 -0
- data/test/test_helper.rb +26 -21
- data/test/unit/exception_handling/exception_catalog_test.rb +15 -14
- data/test/unit/exception_handling/exception_description_test.rb +22 -31
- data/test/unit/exception_handling/exception_info_test.rb +76 -37
- data/test/unit/exception_handling/honeybadger_callbacks_test.rb +46 -9
- data/test/unit/exception_handling/log_error_stub_test.rb +6 -4
- data/test/unit/exception_handling/mailer_test.rb +8 -14
- data/test/unit/exception_handling/methods_test.rb +9 -6
- data/test/unit/exception_handling/sensu_test.rb +6 -4
- data/test/unit/exception_handling_test.rb +279 -364
- metadata +24 -24
- data/views/exception_handling/mailer/exception_notification.html.erb +0 -92
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1538b60821d54ce39c0d24c94378f147f3c1cdea
|
4
|
+
data.tar.gz: d34346f81571519472db2dfd77d94fec6e31cdec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f588ceffb08a99941eb044c48c1de3d843fd9dfdfa6863bb778e95e099a2a7b29ad9081e66d4ec36ffe1cae2c91028d812c2af173e06ba444502ca41fe3c1829
|
7
|
+
data.tar.gz: 0f376e25489540e95224a17c0b1a86ddeb1a7a1fe544f8391c3deef4a74c66068170510ef1f733e83e936461cdb7230214774c8b62397ec4fd1d45f3e6bb76eb
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
# This rubocop config file inherits from our centralized style-guide repository.
|
2
|
+
# If you are looking to update the ruby style guide, be sure to both update the rubocop config
|
3
|
+
# as well as the README.md
|
4
|
+
# https://github.com/Invoca/style-guide/tree/master/ruby
|
5
|
+
inherit_from: https://raw.githubusercontent.com/Invoca/style-guide/master/ruby/.rubocop.yml
|
data/Gemfile
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
5
|
# Specify your gem's dependencies in attr_default.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
|
-
gem 'hobo_support', '2.0.1', git: 'git@github.com:Invoca/hobosupport', ref: 'b9086322274b474a2b5bae507c4885e55d4aa050'
|
7
|
-
gem 'invoca-utils', git: 'git@github.com:Invoca/invoca-utils', ref: '891b8f7e1af0f6324bf85601046907143122e204'
|
8
|
-
gem 'activesupport', '>= 4.2.11.1'
|
9
|
-
gem 'actionpack', '>= 4.2.11.1'
|
10
8
|
gem 'actionmailer', '>= 4.2.11.1'
|
9
|
+
gem 'actionpack', '>= 4.2.11.1'
|
10
|
+
gem 'activesupport', '>= 4.2.11.1'
|
11
11
|
|
12
12
|
group :development do
|
13
|
+
gem 'pry'
|
13
14
|
gem 'rake', '>=0.9'
|
14
|
-
gem 'shoulda', '> 3.1.1'
|
15
15
|
gem 'rr'
|
16
|
-
gem '
|
16
|
+
gem 'rubocop'
|
17
|
+
gem 'shoulda', '> 3.1.1'
|
17
18
|
end
|
18
19
|
|
19
20
|
group :test do
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
GIT
|
2
|
-
remote: git@github.com:Invoca/hobosupport
|
3
|
-
revision: b9086322274b474a2b5bae507c4885e55d4aa050
|
4
|
-
ref: b9086322274b474a2b5bae507c4885e55d4aa050
|
5
|
-
specs:
|
6
|
-
hobo_support (2.0.1)
|
7
|
-
rails (~> 4.2.10)
|
8
|
-
|
9
1
|
GIT
|
10
2
|
remote: git@github.com:Invoca/honeybadger-ruby
|
11
3
|
revision: bb5f2b8a86e4147c38a6270d39ad610fab4dd5e6
|
@@ -13,17 +5,10 @@ GIT
|
|
13
5
|
specs:
|
14
6
|
honeybadger (3.3.1.pre.1)
|
15
7
|
|
16
|
-
GIT
|
17
|
-
remote: git@github.com:Invoca/invoca-utils
|
18
|
-
revision: 891b8f7e1af0f6324bf85601046907143122e204
|
19
|
-
ref: 891b8f7e1af0f6324bf85601046907143122e204
|
20
|
-
specs:
|
21
|
-
invoca-utils (0.0.3)
|
22
|
-
|
23
8
|
PATH
|
24
9
|
remote: .
|
25
10
|
specs:
|
26
|
-
exception_handling (2.
|
11
|
+
exception_handling (2.3.0.pre.1)
|
27
12
|
actionmailer (~> 4.2)
|
28
13
|
actionpack (~> 4.2)
|
29
14
|
activesupport (~> 4.2)
|
@@ -70,19 +55,25 @@ GEM
|
|
70
55
|
thread_safe (~> 0.3, >= 0.3.4)
|
71
56
|
tzinfo (~> 1.1)
|
72
57
|
arel (6.0.4)
|
58
|
+
ast (2.4.0)
|
73
59
|
builder (3.2.3)
|
74
60
|
coderay (1.1.2)
|
75
61
|
concurrent-ruby (1.1.5)
|
76
|
-
contextual_logger (0.
|
62
|
+
contextual_logger (0.3.1)
|
63
|
+
activesupport
|
77
64
|
json
|
78
65
|
crass (1.0.4)
|
79
66
|
erubis (2.7.0)
|
80
67
|
eventmachine (1.2.7)
|
81
68
|
globalid (0.4.2)
|
82
69
|
activesupport (>= 4.2.0)
|
70
|
+
hobo_support (2.2.6)
|
71
|
+
rails (~> 4.2.6)
|
83
72
|
i18n (0.9.5)
|
84
73
|
concurrent-ruby (~> 1.0)
|
85
|
-
|
74
|
+
invoca-utils (0.0.5)
|
75
|
+
jaro_winkler (1.5.3)
|
76
|
+
json (2.3.0)
|
86
77
|
loofah (2.2.3)
|
87
78
|
crass (~> 1.0.2)
|
88
79
|
nokogiri (>= 1.5.9)
|
@@ -92,8 +83,11 @@ GEM
|
|
92
83
|
mini_mime (1.0.1)
|
93
84
|
mini_portile2 (2.4.0)
|
94
85
|
minitest (5.11.3)
|
95
|
-
nokogiri (1.10.
|
86
|
+
nokogiri (1.10.4)
|
96
87
|
mini_portile2 (~> 2.4.0)
|
88
|
+
parallel (1.17.0)
|
89
|
+
parser (2.6.3.0)
|
90
|
+
ast (~> 2.4.0)
|
97
91
|
pry (0.12.2)
|
98
92
|
coderay (~> 1.1.0)
|
99
93
|
method_source (~> 0.9.0)
|
@@ -124,8 +118,17 @@ GEM
|
|
124
118
|
activesupport (= 4.2.11.1)
|
125
119
|
rake (>= 0.8.7)
|
126
120
|
thor (>= 0.18.1, < 2.0)
|
121
|
+
rainbow (3.0.0)
|
127
122
|
rake (12.3.2)
|
128
123
|
rr (1.2.1)
|
124
|
+
rubocop (0.74.0)
|
125
|
+
jaro_winkler (~> 1.5.1)
|
126
|
+
parallel (~> 1.10)
|
127
|
+
parser (>= 2.6)
|
128
|
+
rainbow (>= 2.2.2, < 4.0)
|
129
|
+
ruby-progressbar (~> 1.7)
|
130
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
131
|
+
ruby-progressbar (1.10.1)
|
129
132
|
shoulda (3.6.0)
|
130
133
|
shoulda-context (~> 1.0, >= 1.0.1)
|
131
134
|
shoulda-matchers (~> 3.0)
|
@@ -139,10 +142,11 @@ GEM
|
|
139
142
|
actionpack (>= 4.0)
|
140
143
|
activesupport (>= 4.0)
|
141
144
|
sprockets (>= 3.0.0)
|
142
|
-
thor (0.
|
145
|
+
thor (1.0.1)
|
143
146
|
thread_safe (0.3.6)
|
144
147
|
tzinfo (1.2.5)
|
145
148
|
thread_safe (~> 0.1)
|
149
|
+
unicode-display_width (1.6.0)
|
146
150
|
|
147
151
|
PLATFORMS
|
148
152
|
ruby
|
@@ -152,13 +156,12 @@ DEPENDENCIES
|
|
152
156
|
actionpack (>= 4.2.11.1)
|
153
157
|
activesupport (>= 4.2.11.1)
|
154
158
|
exception_handling!
|
155
|
-
hobo_support (= 2.0.1)!
|
156
159
|
honeybadger (= 3.3.1.pre.1)!
|
157
|
-
invoca-utils!
|
158
160
|
pry
|
159
161
|
rake (>= 0.9)
|
160
162
|
rr
|
163
|
+
rubocop
|
161
164
|
shoulda (> 3.1.1)
|
162
165
|
|
163
166
|
BUNDLED WITH
|
164
|
-
1.
|
167
|
+
1.17.2
|
data/README.md
CHANGED
@@ -31,7 +31,6 @@ For example:
|
|
31
31
|
|
32
32
|
# optional
|
33
33
|
ExceptionHandling.escalation_recipients = ['escalation@example.com']
|
34
|
-
ExceptionHandling.mailer_send_enabled = true # false, will disable exception emails
|
35
34
|
ExceptionHandling.filter_list_filename = "#{Rails.root}/config/exception_filters.yml"
|
36
35
|
ExceptionHandling.email_environment = Rails.env
|
37
36
|
ExceptionHandling.eventmachine_safe = false
|
data/Rakefile
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require "bundler/gem_tasks"
|
3
5
|
require 'rake/testtask'
|
4
6
|
|
5
7
|
namespace :test do
|
6
|
-
|
7
8
|
Rake::TestTask.new do |t|
|
8
9
|
t.name = :unit
|
9
10
|
t.libs << "test"
|
@@ -11,8 +12,7 @@ namespace :test do
|
|
11
12
|
t.verbose = true
|
12
13
|
end
|
13
14
|
Rake::Task['test:unit'].comment = "Run the unit tests"
|
14
|
-
|
15
15
|
end
|
16
16
|
|
17
|
-
task :
|
18
|
-
task :
|
17
|
+
task test: 'test:unit'
|
18
|
+
task default: 'test'
|
data/exception_handling.gemspec
CHANGED
@@ -1,24 +1,26 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('lib/exception_handling/version', __dir__)
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
4
6
|
spec.authors = ["Colin Kelley"]
|
5
7
|
spec.email = ["colindkelley@gmail.com"]
|
6
|
-
spec.description =
|
7
|
-
spec.summary =
|
8
|
+
spec.description = 'Exception handling logger/emailer'
|
9
|
+
spec.summary = "Invoca's exception handling logger/emailer layer, based on exception_notifier. Works with Rails or EventMachine or EventMachine+Synchrony."
|
8
10
|
spec.homepage = "https://github.com/Invoca/exception_handling"
|
9
11
|
|
10
|
-
spec.files = `git ls-files`.split(
|
11
|
-
spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
12
|
+
spec.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
13
|
+
spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
12
14
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/.*\.rb})
|
13
15
|
spec.name = "exception_handling"
|
14
16
|
spec.require_paths = ["lib"]
|
15
17
|
spec.version = ExceptionHandling::VERSION
|
16
18
|
|
17
|
-
spec.add_dependency 'eventmachine', '~> 1.0'
|
18
|
-
spec.add_dependency 'activesupport', '~> 4.2'
|
19
|
-
spec.add_dependency 'actionpack', '~> 4.2'
|
20
19
|
spec.add_dependency 'actionmailer', '~> 4.2'
|
21
|
-
spec.add_dependency '
|
22
|
-
spec.add_dependency '
|
20
|
+
spec.add_dependency 'actionpack', '~> 4.2'
|
21
|
+
spec.add_dependency 'activesupport', '~> 4.2'
|
23
22
|
spec.add_dependency 'contextual_logger'
|
23
|
+
spec.add_dependency 'eventmachine', '~> 1.0'
|
24
|
+
spec.add_dependency 'hobo_support'
|
25
|
+
spec.add_dependency 'invoca-utils', '~> 0.0'
|
24
26
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ExceptionHandling
|
2
4
|
class ExceptionCatalog
|
3
5
|
|
4
6
|
def initialize(filter_path)
|
5
7
|
@filter_path = filter_path
|
6
|
-
@filters = {
|
8
|
+
@filters = {}
|
7
9
|
@filters_last_modified_time = nil
|
8
10
|
end
|
9
11
|
|
@@ -21,7 +23,6 @@ module ExceptionHandling
|
|
21
23
|
load_file
|
22
24
|
end
|
23
25
|
end
|
24
|
-
|
25
26
|
rescue => ex # any exceptions
|
26
27
|
# DO NOT CALL ExceptionHandling.log_error because this method is called from that. It can loop and cause mayhem.
|
27
28
|
ExceptionHandling.write_exception_to_log(ex, "ExceptionCatalog#refresh_filters: #{@filter_path}", Time.now.to_i)
|
@@ -30,9 +31,9 @@ module ExceptionHandling
|
|
30
31
|
def load_file
|
31
32
|
@filters_last_modified_time = last_modified_time # make race condition fall on the side of reloading unnecessarily next time rather than missing a set of changes
|
32
33
|
|
33
|
-
filters = YAML
|
34
|
+
filters = YAML.load_file(@filter_path)
|
34
35
|
filter_hash_values = filters.map { |filter_name, regexes| [filter_name.to_sym, ExceptionDescription.new(filter_name.to_sym, regexes.symbolize_keys)] }
|
35
|
-
@filters = Hash[
|
36
|
+
@filters = Hash[filter_hash_values]
|
36
37
|
end
|
37
38
|
|
38
39
|
def last_modified_time
|
@@ -1,59 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ExceptionHandling
|
2
4
|
class ExceptionDescription
|
3
|
-
MATCH_SECTIONS =
|
5
|
+
MATCH_SECTIONS = [:error, :request, :session, :environment, :backtrace, :event_response].freeze
|
4
6
|
|
5
7
|
CONFIGURATION_SECTIONS = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
}
|
8
|
+
send_to_honeybadger: false, # should be sent to honeybadger?
|
9
|
+
send_metric: true, # should the metric be sent.
|
10
|
+
metric_name: nil, # Will be derived from section name if not passed
|
11
|
+
notes: nil # Will be included in exception email if set, used to keep notes and relevant links
|
12
|
+
}.freeze
|
12
13
|
|
13
|
-
attr_reader :filter_name, :
|
14
|
+
attr_reader :filter_name, :send_to_honeybadger, :send_metric, :metric_name, :notes
|
14
15
|
|
15
16
|
def initialize(filter_name, configuration)
|
16
17
|
@filter_name = filter_name
|
17
18
|
|
18
19
|
invalid_sections = configuration.except(*(CONFIGURATION_SECTIONS.keys + MATCH_SECTIONS))
|
19
|
-
invalid_sections.empty? or raise ArgumentError, "Unknown section: #{invalid_sections.keys.join(
|
20
|
+
invalid_sections.empty? or raise ArgumentError, "Unknown section: #{invalid_sections.keys.join(',')}"
|
20
21
|
|
21
22
|
@configuration = CONFIGURATION_SECTIONS.merge(configuration)
|
22
|
-
@send_email = @configuration[:send_email]
|
23
23
|
@send_to_honeybadger = @configuration[:send_to_honeybadger]
|
24
24
|
@send_metric = @configuration[:send_metric]
|
25
|
-
@metric_name = (@configuration[:metric_name] || @filter_name
|
25
|
+
@metric_name = (@configuration[:metric_name] || @filter_name).to_s.gsub(" ", "_")
|
26
26
|
@notes = @configuration[:notes]
|
27
27
|
|
28
|
-
regex_config = @configuration.reject { |k,v| k.in?(CONFIGURATION_SECTIONS.keys) || v.blank? }
|
28
|
+
regex_config = @configuration.reject { |k, v| k.in?(CONFIGURATION_SECTIONS.keys) || v.blank? }
|
29
29
|
|
30
|
-
@regexes = Hash[regex_config.map { |section, regex| [section, Regexp.new(regex, Regexp::IGNORECASE | Regexp::MULTILINE)
|
30
|
+
@regexes = Hash[regex_config.map { |section, regex| [section, Regexp.new(regex, Regexp::IGNORECASE | Regexp::MULTILINE)] }]
|
31
31
|
|
32
32
|
!@regexes.empty? or raise ArgumentError, "Filter #{filter_name} has all blank regexes: #{configuration.inspect}"
|
33
33
|
end
|
34
34
|
|
35
35
|
def exception_data
|
36
36
|
{
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
"send_metric" => send_metric,
|
38
|
+
"metric_name" => metric_name,
|
39
|
+
"notes" => notes
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
43
|
def match?(exception_data)
|
44
44
|
@regexes.all? do |section, regex|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
case target = exception_data[section.to_s] || exception_data[section]
|
46
|
+
when String
|
47
|
+
regex =~ target
|
48
|
+
when Array
|
49
|
+
target.any? { |row| row =~ regex }
|
50
|
+
when Hash
|
51
|
+
target[:to_s] =~ regex
|
52
|
+
when NilClass
|
53
|
+
false
|
54
|
+
else
|
55
|
+
raise "Unexpected class #{exception_data[section].class.name}"
|
56
|
+
end
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ExceptionHandling
|
2
4
|
class ExceptionInfo
|
3
5
|
|
@@ -6,47 +8,45 @@ module ExceptionHandling
|
|
6
8
|
/^QUERY_/,
|
7
9
|
/^REQUEST_/,
|
8
10
|
/^SERVER_/
|
9
|
-
]
|
10
|
-
|
11
|
-
ENVIRONMENT_OMIT =(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
HTTP_ACCEPT: */*
|
16
|
-
|
17
|
-
|
18
|
-
HTTP_ACCEPT_ENCODING: gzip,
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
TERM:
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
SECTIONS = [:request, :session, :environment, :backtrace, :event_response]
|
49
|
-
HONEYBADGER_CONTEXT_SECTIONS = [:timestamp, :error_class, :exception_context, :server, :scm_revision, :notes, :user_details, :request, :session, :environment, :backtrace, :event_response]
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
ENVIRONMENT_OMIT = <<~EOS.split("\n")
|
14
|
+
CONTENT_TYPE: application/x-www-form-urlencoded
|
15
|
+
GATEWAY_INTERFACE: CGI/1.2
|
16
|
+
HTTP_ACCEPT: */*
|
17
|
+
HTTP_ACCEPT: */*, text/javascript, text/html, application/xml, text/xml, */*
|
18
|
+
HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7
|
19
|
+
HTTP_ACCEPT_ENCODING: gzip, deflate
|
20
|
+
HTTP_ACCEPT_ENCODING: gzip,deflate
|
21
|
+
HTTP_ACCEPT_LANGUAGE: en-us
|
22
|
+
HTTP_CACHE_CONTROL: no-cache
|
23
|
+
HTTP_CONNECTION: Keep-Alive
|
24
|
+
HTTP_HOST: www.invoca.com
|
25
|
+
HTTP_MAX_FORWARDS: 10
|
26
|
+
HTTP_UA_CPU: x86
|
27
|
+
HTTP_VERSION: HTTP/1.1
|
28
|
+
HTTP_X_FORWARDED_HOST: www.invoca.com
|
29
|
+
HTTP_X_FORWARDED_SERVER: www2.invoca.com
|
30
|
+
HTTP_X_REQUESTED_WITH: XMLHttpRequest
|
31
|
+
LANG:
|
32
|
+
PATH: /sbin:/usr/sbin:/bin:/usr/bin
|
33
|
+
PWD: /
|
34
|
+
RAILS_ENV: production
|
35
|
+
RAW_POST_DATA: id=500
|
36
|
+
REMOTE_ADDR: 10.251.34.225
|
37
|
+
SCRIPT_NAME: /
|
38
|
+
SERVER_NAME: www.invoca.com
|
39
|
+
SERVER_PORT: 80
|
40
|
+
SERVER_PROTOCOL: HTTP/1.1
|
41
|
+
SERVER_SOFTWARE: Mongrel 1.1.4
|
42
|
+
SHLVL: 1
|
43
|
+
TERM: linux
|
44
|
+
TERM: xterm-color
|
45
|
+
_: /usr/bin/mongrel_cluster_ctl
|
46
|
+
EOS
|
47
|
+
|
48
|
+
SECTIONS = [:request, :session, :environment, :backtrace, :event_response].freeze
|
49
|
+
HONEYBADGER_CONTEXT_SECTIONS = [:timestamp, :error_class, :exception_context, :server, :scm_revision, :notes, :user_details, :request, :session, :environment, :backtrace, :event_response].freeze
|
50
50
|
|
51
51
|
attr_reader :exception, :controller, :exception_context, :timestamp
|
52
52
|
|
@@ -71,13 +71,19 @@ EOF
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def send_to_honeybadger?
|
74
|
-
ExceptionHandling.
|
74
|
+
ExceptionHandling.honeybadger_defined? && (!exception_description || exception_description.send_to_honeybadger)
|
75
75
|
end
|
76
76
|
|
77
77
|
def honeybadger_context_data
|
78
78
|
@honeybadger_context_data ||= enhanced_data_to_honeybadger_context
|
79
79
|
end
|
80
80
|
|
81
|
+
def controller_name
|
82
|
+
@controller_name ||= if @controller
|
83
|
+
@controller.request.parameters.with_indifferent_access[:controller]
|
84
|
+
end.to_s
|
85
|
+
end
|
86
|
+
|
81
87
|
private
|
82
88
|
|
83
89
|
def controller_from_context(exception_context)
|
@@ -88,10 +94,10 @@ EOF
|
|
88
94
|
exception_message = @exception.message.to_s
|
89
95
|
data = ActiveSupport::HashWithIndifferentAccess.new
|
90
96
|
data[:error_class] = @exception.class.name
|
91
|
-
data[:error_string]= "#{data[:error_class]}: #{ExceptionHandling.encode_utf8(exception_message)}"
|
97
|
+
data[:error_string] = "#{data[:error_class]}: #{ExceptionHandling.encode_utf8(exception_message)}"
|
92
98
|
data[:timestamp] = @timestamp
|
93
99
|
data[:backtrace] = ExceptionHandling.clean_backtrace(@exception)
|
94
|
-
if @exception_context
|
100
|
+
if @exception_context&.is_a?(Hash)
|
95
101
|
# if we are a hash, then we got called from the DebugExceptions rack middleware filter
|
96
102
|
# and we need to do some things different to get the info we want
|
97
103
|
data[:error] = "#{data[:error_class]}: #{ExceptionHandling.encode_utf8(exception_message)}"
|
@@ -118,7 +124,8 @@ EOF
|
|
118
124
|
end
|
119
125
|
|
120
126
|
def enhance_exception_data(data)
|
121
|
-
return if !
|
127
|
+
return if !ExceptionHandling.custom_data_hook
|
128
|
+
|
122
129
|
begin
|
123
130
|
ExceptionHandling.custom_data_hook.call(data)
|
124
131
|
rescue Exception => ex
|
@@ -131,28 +138,29 @@ EOF
|
|
131
138
|
def normalize_exception_data(data)
|
132
139
|
if data[:location].nil?
|
133
140
|
data[:location] = {}
|
134
|
-
if data[:request]
|
141
|
+
if data[:request]&.key?(:params)
|
135
142
|
data[:location][:controller] = data[:request][:params]['controller']
|
136
143
|
data[:location][:action] = data[:request][:params]['action']
|
137
144
|
end
|
138
145
|
end
|
139
|
-
if data[:backtrace]
|
146
|
+
if data[:backtrace]&.first
|
140
147
|
first_line = data[:backtrace].first
|
141
148
|
|
142
149
|
# template exceptions have the line number and filename as the first element in backtrace
|
143
|
-
if matched = first_line.match(
|
144
|
-
backtrace_hash = {
|
145
|
-
|
146
|
-
|
150
|
+
if (matched = first_line.match(/on line #(\d*) of (.*)/i))
|
151
|
+
backtrace_hash = {
|
152
|
+
line: matched[1],
|
153
|
+
file: matched[2]
|
154
|
+
}
|
147
155
|
else
|
148
|
-
backtrace_hash = Hash[* [:file, :line].zip(
|
156
|
+
backtrace_hash = Hash[* [:file, :line].zip(first_line.split(':')[0..1]).flatten]
|
149
157
|
end
|
150
158
|
|
151
|
-
data[:location].merge!(
|
159
|
+
data[:location].merge!(backtrace_hash)
|
152
160
|
end
|
153
161
|
end
|
154
162
|
|
155
|
-
def clean_exception_data(
|
163
|
+
def clean_exception_data(data)
|
156
164
|
if (as_array = data[:backtrace].to_a).size == 1
|
157
165
|
data[:backtrace] = as_array.first.to_s.split(/\n\s*/)
|
158
166
|
end
|
@@ -197,16 +205,16 @@ EOF
|
|
197
205
|
def extract_and_merge_controller_data(data)
|
198
206
|
if @controller
|
199
207
|
data[:request] = {
|
200
|
-
params:
|
201
|
-
rails_root:
|
202
|
-
url:
|
208
|
+
params: @controller.request.parameters.to_hash,
|
209
|
+
rails_root: defined?(Rails) && defined?(Rails.root) ? Rails.root : "Rails.root not defined. Is this a test environment?",
|
210
|
+
url: @controller.complete_request_uri
|
203
211
|
}
|
204
212
|
data[:environment].merge!(@controller.request.env.to_hash)
|
205
213
|
|
206
214
|
@controller.session[:fault_in_session]
|
207
215
|
data[:session] = {
|
208
|
-
key:
|
209
|
-
data:
|
216
|
+
key: @controller.request.session_options[:id],
|
217
|
+
data: @controller.session.to_hash
|
210
218
|
}
|
211
219
|
end
|
212
220
|
end
|
@@ -236,22 +244,22 @@ EOF
|
|
236
244
|
end
|
237
245
|
end
|
238
246
|
|
239
|
-
def add_to_s(
|
240
|
-
data_section[:to_s] = dump_hash(
|
247
|
+
def add_to_s(data_section)
|
248
|
+
data_section[:to_s] = dump_hash(data_section)
|
241
249
|
end
|
242
250
|
|
243
|
-
def dump_hash(
|
244
|
-
result = ""
|
245
|
-
h
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
251
|
+
def dump_hash(h, indent_level = 0)
|
252
|
+
result = +""
|
253
|
+
h&.sort { |a, b| a.to_s <=> b.to_s }&.each do |key, value|
|
254
|
+
result << ' ' * (2 * indent_level)
|
255
|
+
result << "#{key}:"
|
256
|
+
case value
|
257
|
+
when Hash
|
258
|
+
result << "\n" << dump_hash(value, indent_level + 1)
|
259
|
+
else
|
260
|
+
result << " #{value}\n"
|
261
|
+
end
|
253
262
|
end
|
254
|
-
end unless h.nil?
|
255
263
|
result
|
256
264
|
end
|
257
265
|
|