Commit 0d890b146092d9a05833e2fad668b39d24f28396

Authored by Bob Lail
1 parent 34b283ae
Exists in master and in 1 other branch production

extract Fingerprint#generate from ErrorReport

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 -  
app/models/fingerprint.rb 0 → 100644
@@ -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 {
spec/models/fingerprint_spec.rb 0 → 100644
@@ -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 +