debian-mirror-gitlab/app/models/error_tracking/error_event.rb

86 lines
2.2 KiB
Ruby
Raw Normal View History

2021-09-30 23:02:18 +05:30
# frozen_string_literal: true
class ErrorTracking::ErrorEvent < ApplicationRecord
belongs_to :error, counter_cache: :events_count
2022-01-26 12:08:38 +05:30
# Scrub null bytes
attribute :payload, Gitlab::Database::Type::JsonPgSafe.new
2021-09-30 23:02:18 +05:30
validates :payload, json_schema: { filename: 'error_tracking_event_payload' }
validates :error, presence: true
2021-12-11 22:18:48 +05:30
validates :description, presence: true, length: { maximum: 1024 }
validates :level, length: { maximum: 255 }
validates :environment, length: { maximum: 255 }
2021-09-30 23:02:18 +05:30
validates :occurred_at, presence: true
2021-10-27 15:23:28 +05:30
def stacktrace
@stacktrace ||= build_stacktrace
end
# For compatibility with sentry integration
def to_sentry_error_event
Gitlab::ErrorTracking::ErrorEvent.new(
issue_id: error_id,
date_received: occurred_at,
stack_trace_entries: stacktrace
)
end
2021-11-18 22:05:49 +05:30
def release
payload.dig('release')
end
2021-10-27 15:23:28 +05:30
private
def build_stacktrace
raw_stacktrace = find_stacktrace_from_payload
return [] unless raw_stacktrace
raw_stacktrace.map do |entry|
{
'lineNo' => entry['lineno'],
'context' => build_stacktrace_context(entry),
'filename' => entry['filename'],
'function' => entry['function'],
'colNo' => 0 # we don't support colNo yet.
}
end
end
def find_stacktrace_from_payload
exception_entry = payload.dig('exception')
if exception_entry
exception_values = exception_entry.dig('values')
stack_trace_entry = exception_values&.detect { |h| h['stacktrace'].present? }
stack_trace_entry&.dig('stacktrace', 'frames')
end
end
def build_stacktrace_context(entry)
context = []
error_line = entry['context_line']
error_line_no = entry['lineno']
pre_context = entry['pre_context']
post_context = entry['post_context']
2021-12-11 22:18:48 +05:30
context += lines_with_position(pre_context, error_line_no - pre_context.size) if pre_context
2021-10-27 15:23:28 +05:30
context += lines_with_position([error_line], error_line_no)
2021-12-11 22:18:48 +05:30
context += lines_with_position(post_context, error_line_no + 1) if post_context
2021-10-27 15:23:28 +05:30
context.reject(&:blank?)
end
def lines_with_position(lines, position)
return [] if lines.blank?
lines.map.with_index do |line, index|
next unless line
[position + index, line]
end
end
2021-09-30 23:02:18 +05:30
end