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