posthog-ruby 3.15.2 → 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: 87c4c21f1799cc12f7e4792f728194091a4e3abfe28fa26315469c43cbefd6ba
4
- data.tar.gz: 4fa4b2455dcf53c3e805616af1e5eb5ae266729f90832f4c4491147c6626f71d
3
+ metadata.gz: 1091ed7a7995e58f6abbf25b2a45dba44b9c2f15ff152b5a5bf4044856269161
4
+ data.tar.gz: f5f5542aa6c66d00bb22c7362ff4e1613eee4ae20b94cf3fe04933ad798b83b5
5
5
  SHA512:
6
- metadata.gz: b1fce8fb104ff14b8564649222d729fdd6feda8d3382119eee8c034663108edb972932aaee7d17de6d87911816986e55236a554ce19ba107e032bc04f4fdab7d
7
- data.tar.gz: b95fecee03f14f695410f76230e8e1284286c4835cd8f4c2ef66779fc57a27bda7e7c3e892a989207ebd85d1f9531a6034a041dade066d776707ae03c7227661
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 = {
@@ -558,7 +561,7 @@ module PostHog
558
561
  return FeatureFlagEvaluations.new(host: host, distinct_id: distinct_id, flags: {}, groups: groups) if @disabled
559
562
 
560
563
  person_properties, group_properties = add_local_person_and_group_properties(
561
- distinct_id, groups, person_properties, group_properties
564
+ groups, person_properties, group_properties
562
565
  )
563
566
 
564
567
  records = {}
@@ -672,8 +675,8 @@ module PostHog
672
675
  )
673
676
  return {} if @disabled
674
677
 
675
- person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups,
676
- person_properties, group_properties)
678
+ person_properties, group_properties = add_local_person_and_group_properties(groups, person_properties,
679
+ group_properties)
677
680
  @feature_flags_poller.get_all_flags(distinct_id, groups, person_properties, group_properties,
678
681
  only_evaluate_locally)
679
682
  end
@@ -712,8 +715,8 @@ module PostHog
712
715
  return nil if @disabled
713
716
 
714
717
  key = key.to_s
715
- person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups,
716
- person_properties, group_properties)
718
+ person_properties, group_properties = add_local_person_and_group_properties(groups, person_properties,
719
+ group_properties)
717
720
  @feature_flags_poller.get_feature_flag_payload(key, distinct_id, match_value, groups, person_properties,
718
721
  group_properties, only_evaluate_locally)
719
722
  end
@@ -740,7 +743,7 @@ module PostHog
740
743
  return { featureFlags: {}, featureFlagPayloads: {} } if @disabled
741
744
 
742
745
  person_properties, group_properties = add_local_person_and_group_properties(
743
- distinct_id, groups, person_properties, group_properties
746
+ groups, person_properties, group_properties
744
747
  )
745
748
  response = @feature_flags_poller.get_all_flags_and_payloads(
746
749
  distinct_id, groups, person_properties, group_properties, only_evaluate_locally
@@ -902,7 +905,7 @@ module PostHog
902
905
 
903
906
  key = key.to_s
904
907
  person_properties, group_properties = add_local_person_and_group_properties(
905
- distinct_id, groups, person_properties, group_properties
908
+ groups, person_properties, group_properties
906
909
  )
907
910
  feature_flag_response, flag_was_locally_evaluated, request_id, evaluated_at, feature_flag_error, payload =
908
911
  @feature_flags_poller.get_feature_flag(
@@ -1048,7 +1051,7 @@ module PostHog
1048
1051
  @shutdown_mutex.synchronize { @shutdown }
1049
1052
  end
1050
1053
 
1051
- def add_local_person_and_group_properties(distinct_id, groups, person_properties, group_properties)
1054
+ def add_local_person_and_group_properties(groups, person_properties, group_properties)
1052
1055
  groups ||= {}
1053
1056
  person_properties ||= {}
1054
1057
  group_properties ||= {}
@@ -1061,8 +1064,6 @@ module PostHog
1061
1064
  symbolize_keys! value
1062
1065
  end
1063
1066
 
1064
- all_person_properties = { distinct_id: distinct_id }.merge(person_properties)
1065
-
1066
1067
  all_group_properties = {}
1067
1068
  groups&.each do |group_name, group_key|
1068
1069
  all_group_properties[group_name] = {
@@ -1070,7 +1071,7 @@ module PostHog
1070
1071
  }.merge((group_properties && group_properties[group_name]) || {})
1071
1072
  end
1072
1073
 
1073
- [all_person_properties, all_group_properties]
1074
+ [person_properties, all_group_properties]
1074
1075
  end
1075
1076
  end
1076
1077
  end
@@ -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
@@ -922,7 +922,12 @@ module PostHog
922
922
 
923
923
  aggregation_group_type_index = flag_filters[:aggregation_group_type_index]
924
924
  if aggregation_group_type_index.nil?
925
- return match_feature_flag_properties(flag, distinct_id, person_properties, evaluation_cache, @cohorts,
925
+ local_person_properties = person_properties || {}
926
+ unless local_person_properties.key?(:distinct_id) || local_person_properties.key?('distinct_id')
927
+ local_person_properties = local_person_properties.merge(distinct_id: distinct_id)
928
+ end
929
+
930
+ return match_feature_flag_properties(flag, distinct_id, local_person_properties, evaluation_cache, @cohorts,
926
931
  groups: groups, group_properties: group_properties)
927
932
  end
928
933
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostHog
4
- VERSION = '3.15.2'
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.2
4
+ version: 3.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''