From 0d890b146092d9a05833e2fad668b39d24f28396 Mon Sep 17 00:00:00 2001 From: Bob Lail Date: Tue, 18 Jun 2013 10:51:08 -0500 Subject: [PATCH] extract Fingerprint#generate from ErrorReport --- app/models/error_report.rb | 26 ++------------------------ app/models/fingerprint.rb | 41 +++++++++++++++++++++++++++++++++++++++++ spec/models/error_report_spec.rb | 10 ++++------ spec/models/fingerprint_spec.rb | 23 +++++++++++++++++++++++ 4 files changed, 70 insertions(+), 30 deletions(-) create mode 100644 app/models/fingerprint.rb create mode 100644 spec/models/fingerprint_spec.rb diff --git a/app/models/error_report.rb b/app/models/error_report.rb index 56ae893..81bdbe0 100644 --- a/app/models/error_report.rb +++ b/app/models/error_report.rb @@ -1,4 +1,3 @@ -require 'digest/sha1' require 'hoptoad_notifier' ## @@ -23,10 +22,6 @@ class ErrorReport @attributes.each{|k, v| instance_variable_set(:"@#{k}", v) } end - def fingerprint - @fingerprint ||= Digest::SHA1.hexdigest(fingerprint_source.to_s) - end - def rails_env server_environment['environment-name'] || 'development' end @@ -87,25 +82,8 @@ class ErrorReport private - def fingerprint_source - # Find the first backtrace line with a file and line number. - if line = backtrace.lines.detect {|l| l.number.present? && l.file.present? } - # If line exists, only use file and number. - file_or_message = "#{line.file}:#{line.number}" - else - # If no backtrace, use error message - file_or_message = message - end - - { - :file_or_message => file_or_message, - :error_class => error_class, - :component => component, - :action => action, - :environment => rails_env, - :api_key => api_key - } + def fingerprint + @fingerprint ||= Fingerprint.generate(notice, api_key) end end - diff --git a/app/models/fingerprint.rb b/app/models/fingerprint.rb new file mode 100644 index 0000000..0dd435c --- /dev/null +++ b/app/models/fingerprint.rb @@ -0,0 +1,41 @@ +require 'digest/sha1' + +class Fingerprint + attr_reader :notice, :api_key + + def self.generate(notice, api_key) + self.new(notice, api_key).to_s + end + + def initialize(notice, api_key) + @notice = notice + @api_key = api_key + end + + + + def to_s + Digest::SHA1.hexdigest(fingerprint_source.to_s) + end + + def fingerprint_source + # Find the first backtrace line with a file and line number. + if line = notice.backtrace.lines.detect {|l| l.number.present? && l.file.present? } + # If line exists, only use file and number. + file_or_message = "#{line.file}:#{line.number}" + else + # If no backtrace, use error message + file_or_message = notice.message + end + + { + :file_or_message => file_or_message, + :error_class => notice.error_class, + :component => notice.component || 'unknown', + :action => notice.action, + :environment => notice.environment_name || 'development', + :api_key => api_key + } + end + +end diff --git a/spec/models/error_report_spec.rb b/spec/models/error_report_spec.rb index ef04138..c58acf6 100644 --- a/spec/models/error_report_spec.rb +++ b/spec/models/error_report_spec.rb @@ -140,12 +140,10 @@ describe ErrorReport do end it 'find the correct err for the notice' do - Fabricate( - :err, { - :fingerprint => error_report.fingerprint, - :problem => Fabricate(:problem, :resolved => true) - } - ) + err = Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)) + + ErrorReport.any_instance.stub(:fingerprint).and_return(err.fingerprint) + expect { error_report.generate_notice! }.to change { diff --git a/spec/models/fingerprint_spec.rb b/spec/models/fingerprint_spec.rb new file mode 100644 index 0000000..9b6f93c --- /dev/null +++ b/spec/models/fingerprint_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe Fingerprint do + + context '#generate' do + before do + @backtrace = Backtrace.find_or_create(:raw => [ + {"number"=>"425", "file"=>"[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb", "method"=>"_run__2115867319__process_action__262109504__callbacks"}, + {"number"=>"404", "file"=>"[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb", "method"=>"send"}, + {"number"=>"404", "file"=>"[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb", "method"=>"_run_process_action_callbacks"} + ]) + end + + it 'should create the same fingerprint for two notices with the same backtrace' do + notice1 = Fabricate.build(:notice, :backtrace => @backtrace) + notice2 = Fabricate.build(:notice, :backtrace => @backtrace) + + Fingerprint.generate(notice1, "api key").should == Fingerprint.generate(notice2, "api key") + end + end + +end + -- libgit2 0.21.2