airbrake-ruby 1.4.3 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/airbrake-ruby/backtrace.rb +41 -8
- data/lib/airbrake-ruby/nested_exception.rb +3 -2
- data/lib/airbrake-ruby/notice.rb +1 -1
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/backtrace_spec.rb +57 -13
- data/spec/nested_exception_spec.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eaad02409926687bb224ce9b635ba755d70ae2ca
|
4
|
+
data.tar.gz: 4cf429a9c5cfc4f440ee674ab8c06105447e08a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ad0da44bc123bb6c14387d14772796bfefdbbdf8f143285ba839867051771939faf3a2d9ff328f5f3f89231b4a0c7560038eec45601731ec8e6d32d9bd05530
|
7
|
+
data.tar.gz: 26199fd126b11a6ea0a7449ff41591760ffd9642b8eef9c20f7f0e3cb041acb13ba0d1be70d40526a470458374896f086dd3b0c4a7cff657204eb189a02cb165
|
@@ -8,7 +8,7 @@ module Airbrake
|
|
8
8
|
# begin
|
9
9
|
# raise 'Oops!'
|
10
10
|
# rescue
|
11
|
-
# Backtrace.parse(
|
11
|
+
# Backtrace.parse($!, Logger.new(STDOUT))
|
12
12
|
# end
|
13
13
|
module Backtrace
|
14
14
|
##
|
@@ -38,29 +38,61 @@ module Airbrake
|
|
38
38
|
# @return [Regexp] the template that tries to assume what a generic stack
|
39
39
|
# frame might look like, when exception's backtrace is set manually.
|
40
40
|
GENERIC_STACKFRAME_REGEXP = %r{\A
|
41
|
+
(?:from\s)?
|
41
42
|
(?<file>.+) # Matches '/foo/bar/baz.ext'
|
42
43
|
:
|
43
44
|
(?<line>\d+)? # Matches '43' or nothing
|
44
|
-
(
|
45
|
+
(?:
|
46
|
+
in\s`(?<function>.+)' # Matches "in `func'"
|
47
|
+
|
|
48
|
+
:in\s(?<function>.+) # Matches ":in func"
|
49
|
+
)? # ... or nothing
|
45
50
|
\z}x
|
46
51
|
|
52
|
+
##
|
53
|
+
# @return [Regexp] the template that matches exceptions from PL/SQL such as
|
54
|
+
# ORA-06512: at "STORE.LI_LICENSES_PACK", line 1945
|
55
|
+
# @note This is raised by https://github.com/kubo/ruby-oci8
|
56
|
+
OCI_STACKFRAME_REGEXP = /\A
|
57
|
+
(?:
|
58
|
+
ORA-\d{5}
|
59
|
+
:\sat\s
|
60
|
+
(?:"(?<function>.+)",\s)?
|
61
|
+
line\s(?<line>\d+)
|
62
|
+
|
|
63
|
+
#{GENERIC_STACKFRAME_REGEXP}
|
64
|
+
)
|
65
|
+
\z/x
|
66
|
+
|
47
67
|
##
|
48
68
|
# Parses an exception's backtrace.
|
49
69
|
#
|
50
70
|
# @param [Exception] exception The exception, which contains a backtrace to
|
51
71
|
# parse
|
52
72
|
# @return [Array<Hash{Symbol=>String,Integer}>] the parsed backtrace
|
53
|
-
def self.parse(exception)
|
73
|
+
def self.parse(exception, logger)
|
54
74
|
return [] if exception.backtrace.nil? || exception.backtrace.none?
|
55
75
|
|
56
76
|
regexp = if java_exception?(exception)
|
57
77
|
JAVA_STACKFRAME_REGEXP
|
78
|
+
elsif oci_exception?(exception)
|
79
|
+
OCI_STACKFRAME_REGEXP
|
58
80
|
else
|
59
81
|
RUBY_STACKFRAME_REGEXP
|
60
82
|
end
|
61
83
|
|
62
84
|
exception.backtrace.map do |stackframe|
|
63
|
-
|
85
|
+
frame = match_frame(regexp, stackframe)
|
86
|
+
|
87
|
+
unless frame
|
88
|
+
logger.error(
|
89
|
+
"can't parse '#{stackframe}' (please file an issue so we can fix " \
|
90
|
+
"it: https://github.com/airbrake/airbrake-ruby/issues/new)"
|
91
|
+
)
|
92
|
+
frame = { file: nil, line: nil, function: stackframe }
|
93
|
+
end
|
94
|
+
|
95
|
+
stack_frame(frame)
|
64
96
|
end
|
65
97
|
end
|
66
98
|
|
@@ -77,6 +109,10 @@ module Airbrake
|
|
77
109
|
class << self
|
78
110
|
private
|
79
111
|
|
112
|
+
def oci_exception?(exception)
|
113
|
+
defined?(OCIError) && exception.is_a?(OCIError)
|
114
|
+
end
|
115
|
+
|
80
116
|
def stack_frame(match)
|
81
117
|
{ file: match[:file],
|
82
118
|
line: (Integer(match[:line]) if match[:line]),
|
@@ -87,10 +123,7 @@ module Airbrake
|
|
87
123
|
match = regexp.match(stackframe)
|
88
124
|
return match if match
|
89
125
|
|
90
|
-
|
91
|
-
return match if match
|
92
|
-
|
93
|
-
raise Airbrake::Error, "can't parse '#{stackframe}'"
|
126
|
+
GENERIC_STACKFRAME_REGEXP.match(stackframe)
|
94
127
|
end
|
95
128
|
end
|
96
129
|
end
|
@@ -8,15 +8,16 @@ module Airbrake
|
|
8
8
|
# can unwrap. Exceptions that have a longer cause chain will be ignored
|
9
9
|
MAX_NESTED_EXCEPTIONS = 3
|
10
10
|
|
11
|
-
def initialize(exception)
|
11
|
+
def initialize(exception, logger)
|
12
12
|
@exception = exception
|
13
|
+
@logger = logger
|
13
14
|
end
|
14
15
|
|
15
16
|
def as_json
|
16
17
|
unwind_exceptions.map do |exception|
|
17
18
|
{ type: exception.class.name,
|
18
19
|
message: exception.message,
|
19
|
-
backtrace: Backtrace.parse(exception) }
|
20
|
+
backtrace: Backtrace.parse(exception, @logger) }
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
data/lib/airbrake-ruby/notice.rb
CHANGED
data/spec/backtrace_spec.rb
CHANGED
@@ -3,8 +3,6 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe Airbrake::Backtrace do
|
4
4
|
describe ".parse" do
|
5
5
|
context "UNIX backtrace" do
|
6
|
-
let(:backtrace) { described_class.new(AirbrakeTestError.new) }
|
7
|
-
|
8
6
|
let(:parsed_backtrace) do
|
9
7
|
# rubocop:disable Metrics/LineLength, Style/HashSyntax, Style/SpaceAroundOperators, Style/SpaceInsideHashLiteralBraces
|
10
8
|
[{:file=>"/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb", :line=>23, :function=>"<top (required)>"},
|
@@ -24,8 +22,9 @@ RSpec.describe Airbrake::Backtrace do
|
|
24
22
|
end
|
25
23
|
|
26
24
|
it "returns a properly formatted array of hashes" do
|
27
|
-
expect(
|
28
|
-
|
25
|
+
expect(
|
26
|
+
described_class.parse(AirbrakeTestError.new, Logger.new('/dev/null'))
|
27
|
+
).to eq(parsed_backtrace)
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
@@ -45,7 +44,9 @@ RSpec.describe Airbrake::Backtrace do
|
|
45
44
|
end
|
46
45
|
|
47
46
|
it "returns a properly formatted array of hashes" do
|
48
|
-
expect(
|
47
|
+
expect(
|
48
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
49
|
+
).to eq(parsed_backtrace)
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
@@ -69,8 +70,9 @@ RSpec.describe Airbrake::Backtrace do
|
|
69
70
|
it "returns a properly formatted array of hashes" do
|
70
71
|
allow(described_class).to receive(:java_exception?).and_return(true)
|
71
72
|
|
72
|
-
expect(
|
73
|
-
|
73
|
+
expect(
|
74
|
+
described_class.parse(JavaAirbrakeTestError.new, Logger.new('/dev/null'))
|
75
|
+
).to eq(backtrace_array)
|
74
76
|
end
|
75
77
|
end
|
76
78
|
|
@@ -95,7 +97,9 @@ RSpec.describe Airbrake::Backtrace do
|
|
95
97
|
end
|
96
98
|
|
97
99
|
it "returns a properly formatted array of hashes" do
|
98
|
-
expect(
|
100
|
+
expect(
|
101
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
102
|
+
).to eq(parsed_backtrace)
|
99
103
|
end
|
100
104
|
end
|
101
105
|
|
@@ -113,7 +117,9 @@ RSpec.describe Airbrake::Backtrace do
|
|
113
117
|
end
|
114
118
|
|
115
119
|
it "returns a properly formatted array of hashes" do
|
116
|
-
expect(
|
120
|
+
expect(
|
121
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
122
|
+
).to eq(parsed_backtrace)
|
117
123
|
end
|
118
124
|
end
|
119
125
|
end
|
@@ -123,9 +129,20 @@ RSpec.describe Airbrake::Backtrace do
|
|
123
129
|
|
124
130
|
let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(unknown_bt) } }
|
125
131
|
|
126
|
-
it "
|
127
|
-
expect
|
128
|
-
|
132
|
+
it "returns array of hashes where each unknown frame is marked as 'function'" do
|
133
|
+
expect(
|
134
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
135
|
+
).to eq([file: nil, line: nil, function: 'a b c 1 23 321 .rb'])
|
136
|
+
end
|
137
|
+
|
138
|
+
it "logs unknown frames as errors" do
|
139
|
+
out = StringIO.new
|
140
|
+
logger = Logger.new(out)
|
141
|
+
|
142
|
+
expect { described_class.parse(ex, logger) }.
|
143
|
+
to change { out.string }.
|
144
|
+
from('').
|
145
|
+
to(/ERROR -- : can't parse 'a b c 1 23 321 .rb'/)
|
129
146
|
end
|
130
147
|
end
|
131
148
|
|
@@ -143,7 +160,34 @@ RSpec.describe Airbrake::Backtrace do
|
|
143
160
|
end
|
144
161
|
|
145
162
|
it "returns a properly formatted array of hashes" do
|
146
|
-
expect(
|
163
|
+
expect(
|
164
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
165
|
+
).to eq(parsed_backtrace)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "given an Oracle backtrace" do
|
170
|
+
let(:bt) do
|
171
|
+
['ORA-06512: at "STORE.LI_LICENSES_PACK", line 1945',
|
172
|
+
'ORA-06512: at "ACTIVATION.LI_ACT_LICENSES_PACK", line 101',
|
173
|
+
'ORA-06512: at line 2',
|
174
|
+
'from stmt.c:243:in oci8lib_220.bundle']
|
175
|
+
end
|
176
|
+
|
177
|
+
let(:ex) { OCIError.new.tap { |e| e.set_backtrace(bt) } }
|
178
|
+
|
179
|
+
let(:parsed_backtrace) do
|
180
|
+
[{ file: nil, line: 1945, function: 'STORE.LI_LICENSES_PACK' },
|
181
|
+
{ file: nil, line: 101, function: 'ACTIVATION.LI_ACT_LICENSES_PACK' },
|
182
|
+
{ file: nil, line: 2, function: nil },
|
183
|
+
{ file: 'stmt.c', line: 243, function: 'oci8lib_220.bundle' }]
|
184
|
+
end
|
185
|
+
|
186
|
+
it "returns a properly formatted array of hashes" do
|
187
|
+
stub_const('OCIError', AirbrakeTestError)
|
188
|
+
expect(
|
189
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
190
|
+
).to eq(parsed_backtrace)
|
147
191
|
end
|
148
192
|
end
|
149
193
|
end
|
@@ -13,7 +13,7 @@ RSpec.describe Airbrake::NestedException do
|
|
13
13
|
Ruby21Error.raise_error('bingo')
|
14
14
|
end
|
15
15
|
rescue Ruby21Error => ex
|
16
|
-
nested_exception = described_class.new(ex)
|
16
|
+
nested_exception = described_class.new(ex, Logger.new('/dev/null'))
|
17
17
|
exceptions = nested_exception.as_json
|
18
18
|
|
19
19
|
expect(exceptions.size).to eq(2)
|
@@ -40,7 +40,7 @@ RSpec.describe Airbrake::NestedException do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
rescue Ruby21Error => ex
|
43
|
-
nested_exception = described_class.new(ex)
|
43
|
+
nested_exception = described_class.new(ex, Logger.new('/dev/null'))
|
44
44
|
exceptions = nested_exception.as_json
|
45
45
|
|
46
46
|
expect(exceptions.size).to eq(3)
|
@@ -64,7 +64,7 @@ RSpec.describe Airbrake::NestedException do
|
|
64
64
|
end
|
65
65
|
rescue Ruby21Error => ex1
|
66
66
|
ex1.set_backtrace([])
|
67
|
-
nested_exception = described_class.new(ex1)
|
67
|
+
nested_exception = described_class.new(ex1, Logger.new('/dev/null'))
|
68
68
|
exceptions = nested_exception.as_json
|
69
69
|
|
70
70
|
expect(exceptions.size).to eq(2)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: airbrake-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airbrake Technologies, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|