posthog-ruby 3.15.3 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36a73ef4ffe63b9e2c722441bd8d3c5732e8e162ea1431bdc68bc861b2c8a452
4
- data.tar.gz: cf1f040865ce0df9fc7c68d0cac9f0903114b959b1b162d83afecfbdfe8697d1
3
+ metadata.gz: 1091ed7a7995e58f6abbf25b2a45dba44b9c2f15ff152b5a5bf4044856269161
4
+ data.tar.gz: f5f5542aa6c66d00bb22c7362ff4e1613eee4ae20b94cf3fe04933ad798b83b5
5
5
  SHA512:
6
- metadata.gz: 5214a1df75497519ac214d1134549a9d41e98bb16ca7e82df800fca062957ecc17c382472902cd7a8161fe4a6a92786c2fe243ec10663dbbaeb7ae1ddd54562f
7
- data.tar.gz: 3adf9801fe9b1a64427d8c7a0fd4abbc15b78c77fa80566e2be23bc97ff9d3d9808be9ba0513f71d00b814ae9e70da532e82495ce3c4bf763b00ac1adf30b076
6
+ metadata.gz: 8f9bc8bf1c98bce5faf4856db35779fd7436df5d538eeb5ae09c3715feb765ade37d22e903056a974f8942f1e207da6de0cba20cd1c08ee601db56a260b33ee3
7
+ data.tar.gz: 201ed92c1b736ba97e9d76e3221f2297d9f49de0bdee9adc331991d4316db22bf6d014305ef182df6afcc7b1760b2eb7d3026d4337de81c9ce5dbec225239826
@@ -311,15 +311,18 @@ module PostHog
311
311
  # @param flags [PostHog::FeatureFlagEvaluations, nil] A snapshot returned by {#evaluate_flags}.
312
312
  # Forwarded to the inner {#capture} call so the captured `$exception` event carries the
313
313
  # same `$feature/<key>` and `$active_feature_flags` properties as the snapshot.
314
+ # @param mechanism [Hash, nil] How the exception was captured, e.g.
315
+ # `{ 'type' => 'rails', 'handled' => false }` for automatic integrations.
316
+ # Defaults to `{ 'type' => 'generic', 'handled' => true }` for manual captures.
314
317
  # @return [Boolean, nil] Whether the exception event was queued or sent, or nil if the input could not be parsed.
315
- def capture_exception(exception, distinct_id = nil, additional_properties = {}, flags: nil)
318
+ def capture_exception(exception, distinct_id = nil, additional_properties = {}, flags: nil, mechanism: nil)
316
319
  return false if @disabled
317
320
 
318
- exception_info = ExceptionCapture.build_parsed_exception(exception)
321
+ exception_list = ExceptionCapture.build_exception_list(exception, mechanism: mechanism)
319
322
 
320
- return if exception_info.nil?
323
+ return if exception_list.nil?
321
324
 
322
- properties = { '$exception_list' => [exception_info] }
325
+ properties = { '$exception_list' => exception_list }
323
326
  properties.merge!(additional_properties) if additional_properties && !additional_properties.empty?
324
327
 
325
328
  event_data = {
@@ -22,27 +22,72 @@ module PostHog
22
22
  (?: :in\s('|`)(?:([\w:]+)\#)?([^']+)')?$
23
23
  /x
24
24
 
25
+ # Maximum number of exceptions extracted from a single `cause` chain.
26
+ MAX_CHAINED_EXCEPTIONS = 50
27
+
28
+ DEFAULT_MECHANISM = { 'type' => 'generic', 'handled' => true }.freeze
29
+
30
+ # Builds the `$exception_list` payload for an exception, walking its
31
+ # `cause` chain outermost-first (wrapper first, root cause last).
32
+ #
33
+ # @param value [Exception, String, Object] Exception input to parse.
34
+ # @param mechanism [Hash, nil] Mechanism applied to the outermost exception,
35
+ # e.g. `{ 'type' => 'rails', 'handled' => false }`. Chained causes are
36
+ # tagged with `{ 'type' => 'chained', ... }` and parent linkage.
37
+ # @return [Array<Hash>, nil] Parsed exception payloads, or nil when the input is unsupported.
38
+ def self.build_exception_list(value, mechanism: nil)
39
+ root_mechanism = DEFAULT_MECHANISM.merge(mechanism || {})
40
+
41
+ exceptions = []
42
+ seen = {}.compare_by_identity
43
+ current = value
44
+
45
+ while current && exceptions.length < MAX_CHAINED_EXCEPTIONS && !seen.key?(current)
46
+ parsed = build_parsed_exception(current, mechanism: chain_mechanism(root_mechanism, exceptions.length))
47
+ break if parsed.nil?
48
+
49
+ exceptions << parsed
50
+ seen[current] = true
51
+ current = current.respond_to?(:cause) ? current.cause : nil
52
+ end
53
+
54
+ exceptions.empty? ? nil : exceptions
55
+ end
56
+
57
+ # @param root_mechanism [Hash] Mechanism of the outermost exception.
58
+ # @param exception_id [Integer] Zero-based position in the cause chain.
59
+ # @return [Hash]
60
+ def self.chain_mechanism(root_mechanism, exception_id)
61
+ mechanism = root_mechanism.merge('exception_id' => exception_id)
62
+ return mechanism if exception_id.zero?
63
+
64
+ mechanism.merge(
65
+ 'type' => 'chained',
66
+ 'source' => 'cause',
67
+ 'parent_id' => exception_id - 1
68
+ )
69
+ end
70
+
25
71
  # @param value [Exception, String, Object] Exception input to parse.
72
+ # @param mechanism [Hash, nil] Mechanism describing how the exception was captured.
26
73
  # @return [Hash, nil] Parsed exception payload, or nil when the input is unsupported.
27
- def self.build_parsed_exception(value)
74
+ def self.build_parsed_exception(value, mechanism: nil)
28
75
  title, message, backtrace = coerce_exception_input(value)
29
76
  return nil if title.nil?
30
77
 
31
- build_single_exception_from_data(title, message, backtrace)
78
+ build_single_exception_from_data(title, message, backtrace, mechanism: mechanism)
32
79
  end
33
80
 
34
81
  # @param title [String]
35
82
  # @param message [String, nil]
36
83
  # @param backtrace [Array<String>, nil]
84
+ # @param mechanism [Hash, nil]
37
85
  # @return [Hash]
38
- def self.build_single_exception_from_data(title, message, backtrace)
86
+ def self.build_single_exception_from_data(title, message, backtrace, mechanism: nil)
39
87
  {
40
88
  'type' => title,
41
89
  'value' => message || '',
42
- 'mechanism' => {
43
- 'type' => 'generic',
44
- 'handled' => true
45
- },
90
+ 'mechanism' => DEFAULT_MECHANISM.merge(mechanism || {}),
46
91
  'stacktrace' => build_stacktrace(backtrace)
47
92
  }
48
93
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
- VERSION = '3.15.3'
4
+ VERSION = '3.16.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: posthog-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.15.3
4
+ version: 3.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''