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 | 1 | require 'hoptoad_notifier' |
| 3 | 2 | |
| 4 | 3 | ## |
| ... | ... | @@ -23,10 +22,6 @@ class ErrorReport |
| 23 | 22 | @attributes.each{|k, v| instance_variable_set(:"@#{k}", v) } |
| 24 | 23 | end |
| 25 | 24 | |
| 26 | - def fingerprint | |
| 27 | - @fingerprint ||= Digest::SHA1.hexdigest(fingerprint_source.to_s) | |
| 28 | - end | |
| 29 | - | |
| 30 | 25 | def rails_env |
| 31 | 26 | server_environment['environment-name'] || 'development' |
| 32 | 27 | end |
| ... | ... | @@ -87,25 +82,8 @@ class ErrorReport |
| 87 | 82 | |
| 88 | 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 | 87 | end |
| 109 | 88 | |
| 110 | 89 | end |
| 111 | - | ... | ... |
| ... | ... | @@ -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 | 140 | end |
| 141 | 141 | |
| 142 | 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 | 147 | expect { |
| 150 | 148 | error_report.generate_notice! |
| 151 | 149 | }.to change { | ... | ... |
| ... | ... | @@ -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 | + | ... | ... |