Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/error_tracking/error_event.rb')
-rw-r--r--app/models/error_tracking/error_event.rb65
1 files changed, 65 insertions, 0 deletions
diff --git a/app/models/error_tracking/error_event.rb b/app/models/error_tracking/error_event.rb
index ed14a1bce41..4de13de7e2e 100644
--- a/app/models/error_tracking/error_event.rb
+++ b/app/models/error_tracking/error_event.rb
@@ -8,4 +8,69 @@ class ErrorTracking::ErrorEvent < ApplicationRecord
validates :error, presence: true
validates :description, presence: true
validates :occurred_at, presence: true
+
+ 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
+
+ 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']
+
+ context += lines_with_position(pre_context, error_line_no - pre_context.size)
+ context += lines_with_position([error_line], error_line_no)
+ context += lines_with_position(post_context, error_line_no + 1)
+
+ 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
end