Commit 0d890b146092d9a05833e2fad668b39d24f28396
1 parent
34b283ae
Exists in
master
and in
1 other branch
extract Fingerprint#generate from ErrorReport
Showing
4 changed files
with
70 additions
and
30 deletions
Show diff stats
app/models/error_report.rb
1 | -require 'digest/sha1' | ||
2 | require 'hoptoad_notifier' | 1 | require 'hoptoad_notifier' |
3 | 2 | ||
4 | ## | 3 | ## |
@@ -23,10 +22,6 @@ class ErrorReport | @@ -23,10 +22,6 @@ class ErrorReport | ||
23 | @attributes.each{|k, v| instance_variable_set(:"@#{k}", v) } | 22 | @attributes.each{|k, v| instance_variable_set(:"@#{k}", v) } |
24 | end | 23 | end |
25 | 24 | ||
26 | - def fingerprint | ||
27 | - @fingerprint ||= Digest::SHA1.hexdigest(fingerprint_source.to_s) | ||
28 | - end | ||
29 | - | ||
30 | def rails_env | 25 | def rails_env |
31 | server_environment['environment-name'] || 'development' | 26 | server_environment['environment-name'] || 'development' |
32 | end | 27 | end |
@@ -87,25 +82,8 @@ class ErrorReport | @@ -87,25 +82,8 @@ class ErrorReport | ||
87 | 82 | ||
88 | private | 83 | private |
89 | 84 | ||
90 | - def fingerprint_source | ||
91 | - # Find the first backtrace line with a file and line number. | ||
92 | - if line = backtrace.lines.detect {|l| l.number.present? && l.file.present? } | ||
93 | - # If line exists, only use file and number. | ||
94 | - file_or_message = "#{line.file}:#{line.number}" | ||
95 | - else | ||
96 | - # If no backtrace, use error message | ||
97 | - file_or_message = message | ||
98 | - end | ||
99 | - | ||
100 | - { | ||
101 | - :file_or_message => file_or_message, | ||
102 | - :error_class => error_class, | ||
103 | - :component => component, | ||
104 | - :action => action, | ||
105 | - :environment => rails_env, | ||
106 | - :api_key => api_key | ||
107 | - } | 85 | + def fingerprint |
86 | + @fingerprint ||= Fingerprint.generate(notice, api_key) | ||
108 | end | 87 | end |
109 | 88 | ||
110 | end | 89 | end |
111 | - |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +require 'digest/sha1' | ||
2 | + | ||
3 | +class Fingerprint | ||
4 | + attr_reader :notice, :api_key | ||
5 | + | ||
6 | + def self.generate(notice, api_key) | ||
7 | + self.new(notice, api_key).to_s | ||
8 | + end | ||
9 | + | ||
10 | + def initialize(notice, api_key) | ||
11 | + @notice = notice | ||
12 | + @api_key = api_key | ||
13 | + end | ||
14 | + | ||
15 | + | ||
16 | + | ||
17 | + def to_s | ||
18 | + Digest::SHA1.hexdigest(fingerprint_source.to_s) | ||
19 | + end | ||
20 | + | ||
21 | + def fingerprint_source | ||
22 | + # Find the first backtrace line with a file and line number. | ||
23 | + if line = notice.backtrace.lines.detect {|l| l.number.present? && l.file.present? } | ||
24 | + # If line exists, only use file and number. | ||
25 | + file_or_message = "#{line.file}:#{line.number}" | ||
26 | + else | ||
27 | + # If no backtrace, use error message | ||
28 | + file_or_message = notice.message | ||
29 | + end | ||
30 | + | ||
31 | + { | ||
32 | + :file_or_message => file_or_message, | ||
33 | + :error_class => notice.error_class, | ||
34 | + :component => notice.component || 'unknown', | ||
35 | + :action => notice.action, | ||
36 | + :environment => notice.environment_name || 'development', | ||
37 | + :api_key => api_key | ||
38 | + } | ||
39 | + end | ||
40 | + | ||
41 | +end |
spec/models/error_report_spec.rb
@@ -140,12 +140,10 @@ describe ErrorReport do | @@ -140,12 +140,10 @@ describe ErrorReport do | ||
140 | end | 140 | end |
141 | 141 | ||
142 | it 'find the correct err for the notice' do | 142 | it 'find the correct err for the notice' do |
143 | - Fabricate( | ||
144 | - :err, { | ||
145 | - :fingerprint => error_report.fingerprint, | ||
146 | - :problem => Fabricate(:problem, :resolved => true) | ||
147 | - } | ||
148 | - ) | 143 | + err = Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)) |
144 | + | ||
145 | + ErrorReport.any_instance.stub(:fingerprint).and_return(err.fingerprint) | ||
146 | + | ||
149 | expect { | 147 | expect { |
150 | error_report.generate_notice! | 148 | error_report.generate_notice! |
151 | }.to change { | 149 | }.to change { |
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +require 'spec_helper' | ||
2 | + | ||
3 | +describe Fingerprint do | ||
4 | + | ||
5 | + context '#generate' do | ||
6 | + before do | ||
7 | + @backtrace = Backtrace.find_or_create(:raw => [ | ||
8 | + {"number"=>"425", "file"=>"[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb", "method"=>"_run__2115867319__process_action__262109504__callbacks"}, | ||
9 | + {"number"=>"404", "file"=>"[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb", "method"=>"send"}, | ||
10 | + {"number"=>"404", "file"=>"[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb", "method"=>"_run_process_action_callbacks"} | ||
11 | + ]) | ||
12 | + end | ||
13 | + | ||
14 | + it 'should create the same fingerprint for two notices with the same backtrace' do | ||
15 | + notice1 = Fabricate.build(:notice, :backtrace => @backtrace) | ||
16 | + notice2 = Fabricate.build(:notice, :backtrace => @backtrace) | ||
17 | + | ||
18 | + Fingerprint.generate(notice1, "api key").should == Fingerprint.generate(notice2, "api key") | ||
19 | + end | ||
20 | + end | ||
21 | + | ||
22 | +end | ||
23 | + |