airbrake-ruby 6.1.0-java → 6.1.1-java
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 +4 -4
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
- data/lib/airbrake-ruby/nested_exception.rb +10 -1
- data/lib/airbrake-ruby/notice.rb +5 -3
- data/lib/airbrake-ruby/version.rb +1 -1
- metadata +4 -122
- data/spec/airbrake_spec.rb +0 -522
- data/spec/async_sender_spec.rb +0 -65
- data/spec/backtrace_spec.rb +0 -430
- data/spec/benchmark_spec.rb +0 -35
- data/spec/code_hunk_spec.rb +0 -124
- data/spec/config/processor_spec.rb +0 -167
- data/spec/config/validator_spec.rb +0 -204
- data/spec/config_spec.rb +0 -188
- data/spec/context_spec.rb +0 -54
- data/spec/deploy_notifier_spec.rb +0 -50
- data/spec/file_cache_spec.rb +0 -35
- data/spec/filter_chain_spec.rb +0 -124
- data/spec/filters/context_filter_spec.rb +0 -32
- data/spec/filters/dependency_filter_spec.rb +0 -14
- data/spec/filters/exception_attributes_filter_spec.rb +0 -52
- data/spec/filters/gem_root_filter_spec.rb +0 -44
- data/spec/filters/git_last_checkout_filter_spec.rb +0 -61
- data/spec/filters/git_repository_filter_spec.rb +0 -72
- data/spec/filters/git_revision_filter_spec.rb +0 -126
- data/spec/filters/keys_allowlist_spec.rb +0 -204
- data/spec/filters/keys_blocklist_spec.rb +0 -242
- data/spec/filters/root_directory_filter_spec.rb +0 -39
- data/spec/filters/sql_filter_spec.rb +0 -274
- data/spec/filters/system_exit_filter_spec.rb +0 -16
- data/spec/filters/thread_filter_spec.rb +0 -281
- data/spec/fixtures/notroot.txt +0 -7
- data/spec/fixtures/project_root/code.rb +0 -221
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +0 -1
- data/spec/fixtures/project_root/short_file.rb +0 -3
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +0 -5
- data/spec/helpers.rb +0 -9
- data/spec/ignorable_spec.rb +0 -14
- data/spec/inspectable_spec.rb +0 -45
- data/spec/loggable_spec.rb +0 -17
- data/spec/monotonic_time_spec.rb +0 -25
- data/spec/nested_exception_spec.rb +0 -73
- data/spec/notice_notifier/options_spec.rb +0 -269
- data/spec/notice_notifier_spec.rb +0 -361
- data/spec/notice_spec.rb +0 -300
- data/spec/performance_breakdown_spec.rb +0 -11
- data/spec/performance_notifier_spec.rb +0 -645
- data/spec/promise_spec.rb +0 -203
- data/spec/query_spec.rb +0 -11
- data/spec/queue_spec.rb +0 -18
- data/spec/remote_settings/callback_spec.rb +0 -162
- data/spec/remote_settings/settings_data_spec.rb +0 -348
- data/spec/remote_settings_spec.rb +0 -201
- data/spec/request_spec.rb +0 -9
- data/spec/response_spec.rb +0 -110
- data/spec/spec_helper.rb +0 -100
- data/spec/stashable_spec.rb +0 -23
- data/spec/stat_spec.rb +0 -39
- data/spec/sync_sender_spec.rb +0 -168
- data/spec/tdigest_spec.rb +0 -235
- data/spec/thread_pool_spec.rb +0 -196
- data/spec/time_truncate_spec.rb +0 -30
- data/spec/timed_trace_spec.rb +0 -127
- data/spec/truncator_spec.rb +0 -267
@@ -1,221 +0,0 @@
|
|
1
|
-
module Airbrake
|
2
|
-
##
|
3
|
-
# Represents a chunk of information that is meant to be either sent to
|
4
|
-
# Airbrake or ignored completely.
|
5
|
-
#
|
6
|
-
# @since v1.0.0
|
7
|
-
class Notice
|
8
|
-
##
|
9
|
-
# @return [Hash{Symbol=>String}] the information about the notifier library
|
10
|
-
NOTIFIER = {
|
11
|
-
name: 'airbrake-ruby'.freeze,
|
12
|
-
version: Airbrake::AIRBRAKE_RUBY_VERSION,
|
13
|
-
url: 'https://github.com/airbrake/airbrake-ruby'.freeze,
|
14
|
-
}.freeze
|
15
|
-
|
16
|
-
##
|
17
|
-
# @return [Hash{Symbol=>String,Hash}] the information to be displayed in the
|
18
|
-
# Context tab in the dashboard
|
19
|
-
CONTEXT = {
|
20
|
-
os: RUBY_PLATFORM,
|
21
|
-
language: "#{RUBY_ENGINE}/#{RUBY_VERSION}".freeze,
|
22
|
-
notifier: NOTIFIER,
|
23
|
-
}.freeze
|
24
|
-
|
25
|
-
##
|
26
|
-
# @return [Integer] the maxium size of the JSON payload in bytes
|
27
|
-
MAX_NOTICE_SIZE = 64000
|
28
|
-
|
29
|
-
##
|
30
|
-
# @return [Integer] the maximum size of hashes, arrays and strings in the
|
31
|
-
# notice.
|
32
|
-
PAYLOAD_MAX_SIZE = 10000
|
33
|
-
|
34
|
-
##
|
35
|
-
# @return [Array<StandardError>] the list of possible exceptions that might
|
36
|
-
# be raised when an object is converted to JSON
|
37
|
-
JSON_EXCEPTIONS = [
|
38
|
-
IOError,
|
39
|
-
NotImplementedError,
|
40
|
-
JSON::GeneratorError,
|
41
|
-
Encoding::UndefinedConversionError,
|
42
|
-
].freeze
|
43
|
-
|
44
|
-
# @return [Array<Symbol>] the list of keys that can be be overwritten with
|
45
|
-
# {Airbrake::Notice#[]=}
|
46
|
-
WRITABLE_KEYS = %i[notifier context environment session params].freeze
|
47
|
-
|
48
|
-
##
|
49
|
-
# @return [Array<Symbol>] parts of a Notice's payload that can be modified
|
50
|
-
# by the truncator
|
51
|
-
TRUNCATABLE_KEYS = %i[errors environment session params].freeze
|
52
|
-
|
53
|
-
##
|
54
|
-
# @return [String] the name of the host machine
|
55
|
-
HOSTNAME = Socket.gethostname.freeze
|
56
|
-
|
57
|
-
##
|
58
|
-
# @return [String]
|
59
|
-
DEFAULT_SEVERITY = 'error'.freeze
|
60
|
-
|
61
|
-
##
|
62
|
-
# @since v1.7.0
|
63
|
-
# @return [Hash{Symbol=>Object}] the hash with arbitrary objects to be used
|
64
|
-
# in filters
|
65
|
-
attr_reader :stash
|
66
|
-
|
67
|
-
def initialize(config, exception, params = {})
|
68
|
-
@config = config
|
69
|
-
|
70
|
-
@payload = {
|
71
|
-
errors: NestedException.new(config, exception).as_json,
|
72
|
-
context: context,
|
73
|
-
environment: {
|
74
|
-
program_name: $PROGRAM_NAME,
|
75
|
-
},
|
76
|
-
session: {},
|
77
|
-
params: params,
|
78
|
-
}
|
79
|
-
@stash = { exception: exception }
|
80
|
-
@truncator = Airbrake::Truncator.new(PAYLOAD_MAX_SIZE)
|
81
|
-
|
82
|
-
extract_custom_attributes(exception)
|
83
|
-
end
|
84
|
-
|
85
|
-
##
|
86
|
-
# Converts the notice to JSON. Calls +to_json+ on each object inside
|
87
|
-
# notice's payload. Truncates notices, JSON representation of which is
|
88
|
-
# bigger than {MAX_NOTICE_SIZE}.
|
89
|
-
#
|
90
|
-
# @return [Hash{String=>String}, nil]
|
91
|
-
def to_json
|
92
|
-
loop do
|
93
|
-
begin
|
94
|
-
json = @payload.to_json
|
95
|
-
rescue *JSON_EXCEPTIONS => ex
|
96
|
-
@config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")
|
97
|
-
else
|
98
|
-
return json if json && json.bytesize <= MAX_NOTICE_SIZE
|
99
|
-
end
|
100
|
-
|
101
|
-
break if truncate == 0
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
##
|
106
|
-
# Ignores a notice. Ignored notices never reach the Airbrake dashboard.
|
107
|
-
#
|
108
|
-
# @return [void]
|
109
|
-
# @see #ignored?
|
110
|
-
# @note Ignored noticed can't be unignored
|
111
|
-
def ignore!
|
112
|
-
@payload = nil
|
113
|
-
end
|
114
|
-
|
115
|
-
##
|
116
|
-
# Checks whether the notice was ignored.
|
117
|
-
#
|
118
|
-
# @return [Boolean]
|
119
|
-
# @see #ignore!
|
120
|
-
def ignored?
|
121
|
-
@payload.nil?
|
122
|
-
end
|
123
|
-
|
124
|
-
##
|
125
|
-
# Reads a value from notice's payload.
|
126
|
-
# @return [Object]
|
127
|
-
#
|
128
|
-
# @raise [Airbrake::Error] if the notice is ignored
|
129
|
-
def [](key)
|
130
|
-
raise_if_ignored
|
131
|
-
@payload[key]
|
132
|
-
end
|
133
|
-
|
134
|
-
##
|
135
|
-
# Writes a value to the payload hash. Restricts unrecognized
|
136
|
-
# writes.
|
137
|
-
# @example
|
138
|
-
# notice[:params][:my_param] = 'foobar'
|
139
|
-
#
|
140
|
-
# @return [void]
|
141
|
-
# @raise [Airbrake::Error] if the notice is ignored
|
142
|
-
# @raise [Airbrake::Error] if the +key+ is not recognized
|
143
|
-
# @raise [Airbrake::Error] if the root value is not a Hash
|
144
|
-
def []=(key, value)
|
145
|
-
raise_if_ignored
|
146
|
-
|
147
|
-
unless WRITABLE_KEYS.include?(key)
|
148
|
-
raise Airbrake::Error,
|
149
|
-
":#{key} is not recognized among #{WRITABLE_KEYS}"
|
150
|
-
end
|
151
|
-
|
152
|
-
unless value.respond_to?(:to_hash)
|
153
|
-
raise Airbrake::Error, "Got #{value.class} value, wanted a Hash"
|
154
|
-
end
|
155
|
-
|
156
|
-
@payload[key] = value.to_hash
|
157
|
-
end
|
158
|
-
|
159
|
-
private
|
160
|
-
|
161
|
-
def context
|
162
|
-
{
|
163
|
-
version: @config.app_version,
|
164
|
-
# We ensure that root_directory is always a String, so it can always be
|
165
|
-
# converted to JSON in a predictable manner (when it's a Pathname and in
|
166
|
-
# Rails environment, it converts to unexpected JSON).
|
167
|
-
rootDirectory: @config.root_directory.to_s,
|
168
|
-
environment: @config.environment,
|
169
|
-
|
170
|
-
# Make sure we always send hostname.
|
171
|
-
hostname: HOSTNAME,
|
172
|
-
|
173
|
-
severity: DEFAULT_SEVERITY,
|
174
|
-
}.merge(CONTEXT).delete_if { |_key, val| val.nil? || val.empty? }
|
175
|
-
end
|
176
|
-
|
177
|
-
def raise_if_ignored
|
178
|
-
return unless ignored?
|
179
|
-
raise Airbrake::Error, 'cannot access ignored notice'
|
180
|
-
end
|
181
|
-
|
182
|
-
def truncate
|
183
|
-
TRUNCATABLE_KEYS.each { |key| @truncator.truncate(self[key]) }
|
184
|
-
|
185
|
-
new_max_size = @truncator.reduce_max_size
|
186
|
-
if new_max_size == 0
|
187
|
-
@config.logger.error(
|
188
|
-
"#{LOG_LABEL} truncation failed. File an issue at " \
|
189
|
-
"https://github.com/airbrake/airbrake-ruby " \
|
190
|
-
"and attach the following payload: #{@payload}",
|
191
|
-
)
|
192
|
-
end
|
193
|
-
|
194
|
-
new_max_size
|
195
|
-
end
|
196
|
-
|
197
|
-
def extract_custom_attributes(exception)
|
198
|
-
return unless exception.respond_to?(:to_airbrake)
|
199
|
-
attributes = nil
|
200
|
-
|
201
|
-
begin
|
202
|
-
attributes = exception.to_airbrake
|
203
|
-
rescue StandardError => ex
|
204
|
-
@config.logger.error(
|
205
|
-
"#{LOG_LABEL} #{exception.class}#to_airbrake failed: #{ex.class}: #{ex}",
|
206
|
-
)
|
207
|
-
end
|
208
|
-
|
209
|
-
return unless attributes
|
210
|
-
|
211
|
-
begin
|
212
|
-
@payload.merge!(attributes)
|
213
|
-
rescue TypeError
|
214
|
-
@config.logger.error(
|
215
|
-
"#{LOG_LABEL} #{exception.class}#to_airbrake failed:" \
|
216
|
-
" #{attributes} must be a Hash",
|
217
|
-
)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
File without changes
|
@@ -1 +0,0 @@
|
|
1
|
-
loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line
|
data/spec/helpers.rb
DELETED
data/spec/ignorable_spec.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Ignorable do
|
2
|
-
let(:klass) do
|
3
|
-
mod = subject
|
4
|
-
Class.new { include(mod) }
|
5
|
-
end
|
6
|
-
|
7
|
-
it "ignores includee" do
|
8
|
-
instance = klass.new
|
9
|
-
expect(instance).not_to be_ignored
|
10
|
-
|
11
|
-
instance.ignore!
|
12
|
-
expect(instance).to be_ignored
|
13
|
-
end
|
14
|
-
end
|
data/spec/inspectable_spec.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Inspectable do
|
2
|
-
let(:klass) do
|
3
|
-
mod = subject
|
4
|
-
Class.new do
|
5
|
-
include(mod)
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@config = Airbrake::Config.new
|
9
|
-
@filter_chain = nil
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "#inspect" do
|
15
|
-
it "displays object information" do
|
16
|
-
instance = klass.new
|
17
|
-
expect(instance.inspect).to match(/
|
18
|
-
#<:0x\w+\s
|
19
|
-
project_id=""\s
|
20
|
-
project_key=""\s
|
21
|
-
host="http.+"\s
|
22
|
-
filter_chain=nil>
|
23
|
-
/x)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe "#pretty_print" do
|
28
|
-
it "displays object information in a beautiful way" do
|
29
|
-
q = PP.new
|
30
|
-
|
31
|
-
instance = klass.new
|
32
|
-
# Guarding is needed to fix JRuby failure:
|
33
|
-
# NoMethodError: undefined method `[]' for nil:NilClass
|
34
|
-
q.guard_inspect_key { instance.pretty_print(q) }
|
35
|
-
|
36
|
-
expect(q.output).to match(/
|
37
|
-
#<:0x\w+\s
|
38
|
-
project_id=""\s
|
39
|
-
project_key=""\s
|
40
|
-
host="http.+"\s
|
41
|
-
filter_chain=nil
|
42
|
-
/x)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/spec/loggable_spec.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::Loggable do
|
2
|
-
describe ".instance" do
|
3
|
-
it "returns a logger" do
|
4
|
-
expect(described_class.instance).to be_a(Logger)
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "#logger" do
|
9
|
-
subject(:class_with_logger) do
|
10
|
-
Class.new { include Airbrake::Loggable }.new
|
11
|
-
end
|
12
|
-
|
13
|
-
it "returns a logger that has Logger::WARN severity" do
|
14
|
-
expect(class_with_logger.logger.level).to eq(Logger::WARN)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/spec/monotonic_time_spec.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::MonotonicTime do
|
2
|
-
subject(:monotonic_time) { described_class }
|
3
|
-
|
4
|
-
describe ".time_in_ms" do
|
5
|
-
it "returns monotonic time in milliseconds" do
|
6
|
-
expect(monotonic_time.time_in_ms).to be_a(Float)
|
7
|
-
end
|
8
|
-
|
9
|
-
it "always returns time in the future" do
|
10
|
-
old_time = monotonic_time.time_in_ms
|
11
|
-
expect(monotonic_time.time_in_ms).to be > old_time
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe ".time_in_s" do
|
16
|
-
it "returns monotonic time in seconds" do
|
17
|
-
expect(monotonic_time.time_in_s).to be_a(Float)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "always returns time in the future" do
|
21
|
-
old_time = monotonic_time.time_in_s
|
22
|
-
expect(monotonic_time.time_in_s).to be > old_time
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::NestedException do
|
2
|
-
describe "#as_json" do
|
3
|
-
context "given exceptions with backtraces" do
|
4
|
-
# rubocop:disable RSpec/MultipleExpectations
|
5
|
-
it "unwinds nested exceptions" do
|
6
|
-
begin
|
7
|
-
raise AirbrakeTestError
|
8
|
-
rescue AirbrakeTestError
|
9
|
-
Ruby21Error.raise_error('bingo')
|
10
|
-
end
|
11
|
-
rescue Ruby21Error => ex
|
12
|
-
nested_exception = described_class.new(ex)
|
13
|
-
exceptions = nested_exception.as_json
|
14
|
-
|
15
|
-
expect(exceptions.size).to eq(2)
|
16
|
-
expect(exceptions[0][:message]).to eq('bingo')
|
17
|
-
expect(exceptions[1][:message]).to eq('App crashed!')
|
18
|
-
expect(exceptions[0][:backtrace]).not_to be_empty
|
19
|
-
expect(exceptions[1][:backtrace]).not_to be_empty
|
20
|
-
end
|
21
|
-
# rubocop:enable RSpec/MultipleExpectations
|
22
|
-
|
23
|
-
# rubocop:disable RSpec/MultipleExpectations
|
24
|
-
it "unwinds no more than 3 nested exceptions" do
|
25
|
-
begin
|
26
|
-
raise AirbrakeTestError
|
27
|
-
rescue AirbrakeTestError
|
28
|
-
begin
|
29
|
-
Ruby21Error.raise_error('bongo')
|
30
|
-
rescue Ruby21Error
|
31
|
-
begin
|
32
|
-
Ruby21Error.raise_error('bango')
|
33
|
-
rescue Ruby21Error
|
34
|
-
Ruby21Error.raise_error('bingo')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
rescue Ruby21Error => ex
|
39
|
-
nested_exception = described_class.new(ex)
|
40
|
-
exceptions = nested_exception.as_json
|
41
|
-
|
42
|
-
expect(exceptions.size).to eq(3)
|
43
|
-
expect(exceptions[0][:message]).to eq('bingo')
|
44
|
-
expect(exceptions[1][:message]).to eq('bango')
|
45
|
-
expect(exceptions[2][:message]).to eq('bongo')
|
46
|
-
expect(exceptions[0][:backtrace]).not_to be_empty
|
47
|
-
expect(exceptions[1][:backtrace]).not_to be_empty
|
48
|
-
end
|
49
|
-
# rubocop:enable RSpec/MultipleExpectations
|
50
|
-
end
|
51
|
-
|
52
|
-
context "given exceptions without backtraces" do
|
53
|
-
# rubocop:disable RSpec/MultipleExpectations
|
54
|
-
it "sets backtrace to nil" do
|
55
|
-
begin
|
56
|
-
raise AirbrakeTestError
|
57
|
-
rescue AirbrakeTestError => ex2
|
58
|
-
ex2.set_backtrace([])
|
59
|
-
Ruby21Error.raise_error('bingo')
|
60
|
-
end
|
61
|
-
rescue Ruby21Error => ex1
|
62
|
-
ex1.set_backtrace([])
|
63
|
-
nested_exception = described_class.new(ex1)
|
64
|
-
exceptions = nested_exception.as_json
|
65
|
-
|
66
|
-
expect(exceptions.size).to eq(2)
|
67
|
-
expect(exceptions[0][:backtrace]).to be_empty
|
68
|
-
expect(exceptions[1][:backtrace]).to be_empty
|
69
|
-
end
|
70
|
-
# rubocop:enable RSpec/MultipleExpectations
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,269 +0,0 @@
|
|
1
|
-
RSpec.describe Airbrake::NoticeNotifier do
|
2
|
-
subject(:notice_notifier) { described_class.new }
|
3
|
-
|
4
|
-
let(:project_id) { 105138 }
|
5
|
-
let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
|
6
|
-
let(:localhost) { 'http://localhost:8080' }
|
7
|
-
|
8
|
-
let(:endpoint) do
|
9
|
-
"https://api.airbrake.io/api/v3/projects/#{project_id}/notices"
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:params) { {} }
|
13
|
-
let(:ex) { AirbrakeTestError.new }
|
14
|
-
|
15
|
-
before do
|
16
|
-
stub_request(:post, endpoint).to_return(status: 201, body: '{}')
|
17
|
-
|
18
|
-
Airbrake::Config.instance = Airbrake::Config.new(
|
19
|
-
project_id: project_id,
|
20
|
-
project_key: project_key,
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "options" do
|
25
|
-
describe ":host" do
|
26
|
-
context "when custom" do
|
27
|
-
shared_examples 'endpoint' do |host, endpoint, title|
|
28
|
-
before { Airbrake::Config.instance.merge(host: host) }
|
29
|
-
|
30
|
-
example(title) do
|
31
|
-
stub_request(:post, endpoint).to_return(status: 201, body: '{}')
|
32
|
-
notice_notifier.notify_sync(ex)
|
33
|
-
|
34
|
-
expect(a_request(:post, endpoint)).to have_been_made.once
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
path = '/api/v3/projects/105138/notices'
|
39
|
-
|
40
|
-
context "given a full host with port" do
|
41
|
-
include_examples('endpoint', localhost = 'http://localhost:8080',
|
42
|
-
URI.join(localhost, path),
|
43
|
-
"sends notices to the specified host's endpoint")
|
44
|
-
end
|
45
|
-
|
46
|
-
context "given a full host" do
|
47
|
-
include_examples('endpoint', localhost = 'http://localhost',
|
48
|
-
URI.join(localhost, path),
|
49
|
-
"assumes port 80 by default")
|
50
|
-
end
|
51
|
-
|
52
|
-
context "given a host without scheme" do
|
53
|
-
include_examples 'endpoint', localhost = 'localhost:8080',
|
54
|
-
URI.join("https://#{localhost}", path),
|
55
|
-
"assumes https by default"
|
56
|
-
end
|
57
|
-
|
58
|
-
context "given only hostname" do
|
59
|
-
include_examples 'endpoint', localhost = 'localhost',
|
60
|
-
URI.join("https://#{localhost}", path),
|
61
|
-
"assumes https and port 80 by default"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe ":root_directory" do
|
67
|
-
before do
|
68
|
-
notice_notifier.add_filter(
|
69
|
-
Airbrake::Filters::RootDirectoryFilter.new('/home/kyrylo/code'),
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
it "filters out frames" do
|
74
|
-
notice_notifier.notify_sync(ex)
|
75
|
-
|
76
|
-
expect(
|
77
|
-
a_request(:post, endpoint)
|
78
|
-
.with(body: %r|{"file":"/PROJECT_ROOT/airbrake/ruby/spec/airbrake_spec.+|),
|
79
|
-
).to have_been_made.once
|
80
|
-
end
|
81
|
-
|
82
|
-
context "when present and is a" do
|
83
|
-
shared_examples 'root directory' do |dir|
|
84
|
-
before { Airbrake::Config.instance.merge(root_directory: dir) }
|
85
|
-
|
86
|
-
it "being included into the notice's payload" do
|
87
|
-
notice_notifier.notify_sync(ex)
|
88
|
-
expect(
|
89
|
-
a_request(:post, endpoint)
|
90
|
-
.with(body: %r{"rootDirectory":"/bingo/bango"}),
|
91
|
-
).to have_been_made.once
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context "String" do
|
96
|
-
include_examples 'root directory', '/bingo/bango'
|
97
|
-
end
|
98
|
-
|
99
|
-
context "Pathname" do
|
100
|
-
include_examples 'root directory', Pathname.new('/bingo/bango')
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# rubocop:disable RSpec/MultipleMemoizedHelpers
|
106
|
-
describe ":proxy" do
|
107
|
-
let(:proxy) do
|
108
|
-
WEBrick::HTTPServer.new(
|
109
|
-
Port: 0,
|
110
|
-
Logger: WEBrick::Log.new('/dev/null'),
|
111
|
-
AccessLog: [],
|
112
|
-
)
|
113
|
-
end
|
114
|
-
|
115
|
-
let(:requests) { Queue.new }
|
116
|
-
|
117
|
-
let(:proxy_params) do
|
118
|
-
{ host: 'localhost',
|
119
|
-
port: proxy.config[:Port],
|
120
|
-
user: 'user',
|
121
|
-
password: 'password' }
|
122
|
-
end
|
123
|
-
|
124
|
-
before do
|
125
|
-
Airbrake::Config.instance.merge(
|
126
|
-
proxy: proxy_params,
|
127
|
-
host: "http://localhost:#{proxy.config[:Port]}",
|
128
|
-
)
|
129
|
-
|
130
|
-
proxy.mount_proc '/' do |req, res|
|
131
|
-
requests << req
|
132
|
-
res.status = 201
|
133
|
-
res.body = "OK\n"
|
134
|
-
end
|
135
|
-
|
136
|
-
Thread.new { proxy.start }
|
137
|
-
end
|
138
|
-
|
139
|
-
after { proxy.stop }
|
140
|
-
|
141
|
-
it "is being used if configured" do
|
142
|
-
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
|
143
|
-
skip(
|
144
|
-
"We use Webmock 2, which doesn't support Ruby 2.6+. It's " \
|
145
|
-
"safe to run this test on 2.6+ once we upgrade to Webmock 3.5+",
|
146
|
-
)
|
147
|
-
end
|
148
|
-
notice_notifier.notify_sync(ex)
|
149
|
-
|
150
|
-
proxied_request = requests.pop(true)
|
151
|
-
|
152
|
-
expect(proxied_request.header['proxy-authorization'].first)
|
153
|
-
.to eq('Basic dXNlcjpwYXNzd29yZA==')
|
154
|
-
|
155
|
-
# rubocop:disable Layout/LineLength
|
156
|
-
expect(proxied_request.request_line)
|
157
|
-
.to eq("POST http://localhost:#{proxy.config[:Port]}/api/v3/projects/105138/notices HTTP/1.1\r\n")
|
158
|
-
# rubocop:enable Layout/LineLength
|
159
|
-
end
|
160
|
-
end
|
161
|
-
# rubocop:enable RSpec/MultipleMemoizedHelpers
|
162
|
-
|
163
|
-
describe ":environment" do
|
164
|
-
context "when present" do
|
165
|
-
before { Airbrake::Config.instance.merge(environment: :production) }
|
166
|
-
|
167
|
-
it "being included into the notice's payload" do
|
168
|
-
notice_notifier.notify_sync(ex)
|
169
|
-
expect(
|
170
|
-
a_request(:post, endpoint)
|
171
|
-
.with(body: /"context":{.*"environment":"production".*}/),
|
172
|
-
).to have_been_made.once
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe ":ignore_environments" do
|
178
|
-
shared_examples 'sent notice' do |params|
|
179
|
-
before { Airbrake::Config.instance.merge(params) }
|
180
|
-
|
181
|
-
it "sends a notice" do
|
182
|
-
notice_notifier.notify_sync(ex)
|
183
|
-
expect(a_request(:post, endpoint)).to have_been_made
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
shared_examples 'ignored notice' do |params|
|
188
|
-
before { Airbrake::Config.instance.merge(params) }
|
189
|
-
|
190
|
-
it "ignores exceptions occurring in envs that were not configured" do
|
191
|
-
notice_notifier.notify_sync(ex)
|
192
|
-
expect(a_request(:post, endpoint)).not_to have_been_made
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
context "when env is set and ignore_environments doesn't mention it" do
|
197
|
-
params = {
|
198
|
-
environment: :development,
|
199
|
-
ignore_environments: [:production],
|
200
|
-
}
|
201
|
-
|
202
|
-
include_examples 'sent notice', params
|
203
|
-
end
|
204
|
-
|
205
|
-
context "when the current env and notify envs are the same" do
|
206
|
-
params = {
|
207
|
-
environment: :development,
|
208
|
-
ignore_environments: %i[production development],
|
209
|
-
}
|
210
|
-
|
211
|
-
include_examples 'ignored notice', params
|
212
|
-
|
213
|
-
it "returns early and doesn't try to parse the given exception" do
|
214
|
-
allow(Airbrake::Notice).to receive(:new)
|
215
|
-
|
216
|
-
expect(notice_notifier.notify_sync(ex))
|
217
|
-
.to eq('error' => "current environment 'development' is ignored")
|
218
|
-
|
219
|
-
expect(Airbrake::Notice).not_to have_received(:new)
|
220
|
-
end
|
221
|
-
|
222
|
-
it "doesn't make an HTTP request" do
|
223
|
-
expect(a_request(:post, endpoint)).not_to have_been_made
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
context "when the current env is not set and notify envs are present" do
|
228
|
-
params = { ignore_environments: %i[production development] }
|
229
|
-
|
230
|
-
include_examples 'sent notice', params
|
231
|
-
end
|
232
|
-
|
233
|
-
context "when the current env is set and notify envs aren't" do
|
234
|
-
include_examples 'sent notice', environment: :development
|
235
|
-
end
|
236
|
-
|
237
|
-
context "when ignore_environments specifies a Regexp pattern" do
|
238
|
-
params = {
|
239
|
-
environment: :testing,
|
240
|
-
ignore_environments: ['staging', /test.+/],
|
241
|
-
}
|
242
|
-
|
243
|
-
include_examples 'ignored notice', params
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
describe ":blocklist_keys" do
|
248
|
-
# Fixes https://github.com/airbrake/airbrake-ruby/issues/276
|
249
|
-
context "when specified along with :allowlist_keys" do
|
250
|
-
context "and when context payload is present" do
|
251
|
-
before do
|
252
|
-
Airbrake::Config.instance.merge(
|
253
|
-
blocklist_keys: %i[password password_confirmation],
|
254
|
-
allowlist_keys: [:email, /user/i, 'account_id'],
|
255
|
-
)
|
256
|
-
end
|
257
|
-
|
258
|
-
it "sends a notice" do
|
259
|
-
notice = notice_notifier.build_notice(ex)
|
260
|
-
notice[:context][:headers] = 'banana'
|
261
|
-
notice_notifier.notify_sync(notice)
|
262
|
-
|
263
|
-
expect(a_request(:post, endpoint)).to have_been_made
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|