Class: RailsErrorDashboard::Services::ErrorHashGenerator
- Inherits:
-
Object
- Object
- RailsErrorDashboard::Services::ErrorHashGenerator
- Defined in:
- lib/rails_error_dashboard/services/error_hash_generator.rb
Overview
Pure algorithm: Generate consistent hash for error deduplication
No database access — accepts exception data, returns a hash string. Same hash = same error type for grouping purposes.
Two entry points:
-
‘.call(exception, …)` — used by LogError command (exception-based)
-
‘.from_attributes(…)` — used by ErrorLog model callback (attribute-based)
Class Method Summary collapse
-
.call(exception, controller_name: nil, action_name: nil, application_id: nil) ⇒ String
Generate hash from an exception object (used by LogError command).
-
.extract_app_frame(backtrace) ⇒ String?
Extract first meaningful app code frame from backtrace.
-
.from_attributes(error_type:, message: nil, backtrace: nil, controller_name: nil, action_name: nil, application_id: nil) ⇒ String
Generate hash from error attributes (used by ErrorLog model callback) Uses ErrorNormalizer for smarter normalization and significant frame extraction.
-
.normalize_message(message) ⇒ String?
Normalize dynamic values in error messages for consistent hashing.
Class Method Details
.call(exception, controller_name: nil, action_name: nil, application_id: nil) ⇒ String
Generate hash from an exception object (used by LogError command)
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/rails_error_dashboard/services/error_hash_generator.rb', line 24 def self.call(exception, controller_name: nil, action_name: nil, application_id: nil) = (exception.) file_path = extract_app_frame(exception.backtrace) digest_input = [ exception.class.name, , file_path, controller_name, action_name, application_id.to_s ].compact.join("|") Digest::SHA256.hexdigest(digest_input)[0..15] end |
.extract_app_frame(backtrace) ⇒ String?
Extract first meaningful app code frame from backtrace
80 81 82 83 84 85 86 87 88 |
# File 'lib/rails_error_dashboard/services/error_hash_generator.rb', line 80 def self.extract_app_frame(backtrace) return nil if backtrace.nil? first_app_frame = backtrace.find { |frame| !frame.include?("/gems/") } first_app_frame&.split(":")&.first end |
.from_attributes(error_type:, message: nil, backtrace: nil, controller_name: nil, action_name: nil, application_id: nil) ⇒ String
Generate hash from error attributes (used by ErrorLog model callback) Uses ErrorNormalizer for smarter normalization and significant frame extraction
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rails_error_dashboard/services/error_hash_generator.rb', line 49 def self.from_attributes(error_type:, message: nil, backtrace: nil, controller_name: nil, action_name: nil, application_id: nil) = ErrorNormalizer.normalize() significant_frames = ErrorNormalizer.extract_significant_frames(backtrace, count: 3) digest_input = [ error_type, , significant_frames, controller_name, action_name, application_id.to_s ].compact.join("|") Digest::SHA256.hexdigest(digest_input)[0..15] end |
.normalize_message(message) ⇒ String?
Normalize dynamic values in error messages for consistent hashing
68 69 70 71 72 73 74 75 |
# File 'lib/rails_error_dashboard/services/error_hash_generator.rb', line 68 def self.() &.gsub(/0x[0-9a-f]+/i, "HEX") # Replace hex addresses (before numbers) &.gsub(/#<[^>]+>/, "#<OBJ>") # Replace object inspections &.gsub(/\d+/, "N") # Replace numbers &.gsub(/"[^"]*"/, '""') # Replace double-quoted strings &.gsub(/'[^']*'/, "''") # Replace single-quoted strings end |