Module: PostHog::ExceptionCapture
- Defined in:
- lib/posthog/exception_capture.rb
Constant Summary collapse
- RUBY_INPUT_FORMAT =
/ ^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>): (\d+) (?: :in\s('|`)(?:([\w:]+)\#)?([^']+)')?$ /x
Class Method Summary collapse
- .add_context_lines(frame, file_path, lineno, context_size = 5) ⇒ Object
- .build_parsed_exception(value) ⇒ Object
- .build_single_exception_from_data(title, message, backtrace) ⇒ Object
- .build_stacktrace(backtrace) ⇒ Object
- .coerce_exception_input(value) ⇒ Object
- .gem_path?(path) ⇒ Boolean
- .parse_backtrace_line(line) ⇒ Object
Class Method Details
.add_context_lines(frame, file_path, lineno, context_size = 5) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/posthog/exception_capture.rb', line 82 def self.add_context_lines(frame, file_path, lineno, context_size = 5) lines = File.readlines(file_path) return if lines.empty? return unless lineno.positive? && lineno <= lines.length pre_context_start = [lineno - context_size, 1].max post_context_end = [lineno + context_size, lines.length].min frame['context_line'] = lines[lineno - 1].chomp frame['pre_context'] = lines[(pre_context_start - 1)...(lineno - 1)].map(&:chomp) if pre_context_start < lineno frame['post_context'] = lines[lineno...(post_context_end)].map(&:chomp) if post_context_end > lineno rescue StandardError # Silently ignore file read errors end |
.build_parsed_exception(value) ⇒ Object
21 22 23 24 25 26 |
# File 'lib/posthog/exception_capture.rb', line 21 def self.build_parsed_exception(value) title, , backtrace = coerce_exception_input(value) return nil if title.nil? build_single_exception_from_data(title, , backtrace) end |
.build_single_exception_from_data(title, message, backtrace) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/posthog/exception_capture.rb', line 28 def self.build_single_exception_from_data(title, , backtrace) { 'type' => title, 'value' => || '', 'mechanism' => { 'type' => 'generic', 'handled' => true }, 'stacktrace' => build_stacktrace(backtrace) } end |
.build_stacktrace(backtrace) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/posthog/exception_capture.rb', line 40 def self.build_stacktrace(backtrace) return nil unless backtrace && !backtrace.empty? frames = backtrace.first(50).map do |line| parse_backtrace_line(line) end.compact.reverse { 'type' => 'raw', 'frames' => frames } end |
.coerce_exception_input(value) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/posthog/exception_capture.rb', line 100 def self.coerce_exception_input(value) if value.is_a?(String) title = 'Error' = value backtrace = nil elsif value.respond_to?(:backtrace) && value.respond_to?(:message) title = value.class.to_s = value. || '' backtrace = value.backtrace else return [nil, nil, nil] end [title, , backtrace] end |
.gem_path?(path) ⇒ Boolean
75 76 77 78 79 80 |
# File 'lib/posthog/exception_capture.rb', line 75 def self.gem_path?(path) path.include?('/gems/') || path.include?('/ruby/') || path.include?('/.rbenv/') || path.include?('/.rvm/') end |
.parse_backtrace_line(line) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/posthog/exception_capture.rb', line 53 def self.parse_backtrace_line(line) match = line.match(RUBY_INPUT_FORMAT) return nil unless match file = match[1] lineno = match[2].to_i method_name = match[5] frame = { 'filename' => File.basename(file), 'abs_path' => file, 'lineno' => lineno, 'function' => method_name, 'in_app' => !gem_path?(file), 'platform' => 'ruby' } add_context_lines(frame, file, lineno) if File.exist?(file) frame end |