posthog-rails 3.18.0 → 3.18.1
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 +4 -4
- data/lib/posthog/rails/capture_exceptions.rb +2 -1
- data/lib/posthog/rails/error_subscriber.rb +4 -0
- data/lib/posthog/rails/version.rb +1 -1
- data/lib/posthog/rails.rb +38 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0a7b0ad61d233027e7990c402f2ca9f851f35122859cdeb18ec7887144484e34
|
|
4
|
+
data.tar.gz: e42012a9157687d9f63928c3bf1d7b7155141bec78322d1aa6f5195471f2107a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ec025711df0d6c208d771d49ab18dfc8771c5de9ec73f6a0d3bded20e3dbe3ac3e43c2241563391f596200c57baec4d59f9174d18bae6f46d7f213e75b8680f
|
|
7
|
+
data.tar.gz: b54c95eea70699a408d3209cda57f1ab641c881998ce0d1c7bde9d16eb94a0dec351b1c530202a790e78a9be22e29da4a9a663e8396f59dd7f6da137f7784455
|
|
@@ -60,12 +60,13 @@ module PostHog
|
|
|
60
60
|
distinct_id = extract_distinct_id(env)
|
|
61
61
|
additional_properties = build_properties(request, env)
|
|
62
62
|
|
|
63
|
-
PostHog.capture_exception(
|
|
63
|
+
captured = PostHog.capture_exception(
|
|
64
64
|
exception,
|
|
65
65
|
distinct_id,
|
|
66
66
|
additional_properties,
|
|
67
67
|
mechanism: { 'type' => 'rails', 'handled' => false }
|
|
68
68
|
)
|
|
69
|
+
PostHog::Rails.mark_web_exception_captured(exception) if captured
|
|
69
70
|
rescue StandardError => e
|
|
70
71
|
PostHog::Logging.logger.error("Failed to capture exception: #{e.message}")
|
|
71
72
|
PostHog::Logging.logger.error("Backtrace: #{e.backtrace&.first(5)&.join("\n")}")
|
|
@@ -23,6 +23,10 @@ module PostHog
|
|
|
23
23
|
# Skip if in a web request - CaptureExceptions middleware will handle it
|
|
24
24
|
# with richer context (URL, params, controller, etc.)
|
|
25
25
|
return if PostHog::Rails.in_web_request?
|
|
26
|
+
# ActionDispatch::Executor reports the exception once the response has
|
|
27
|
+
# unwound past our middleware, so the flag above is already cleared.
|
|
28
|
+
# CaptureExceptions marks what it captured to catch that late report.
|
|
29
|
+
return if PostHog::Rails.web_exception_captured?(error)
|
|
26
30
|
return if PostHog::Rails.config&.auto_instrument_active_job &&
|
|
27
31
|
PostHog::Rails.active_job_exception_captured?(error)
|
|
28
32
|
|
data/lib/posthog/rails.rb
CHANGED
|
@@ -21,8 +21,10 @@ module PostHog
|
|
|
21
21
|
# Thread-local key for tracking web request context
|
|
22
22
|
IN_WEB_REQUEST_KEY = :posthog_in_web_request
|
|
23
23
|
ACTIVE_JOB_CAPTURED_EXCEPTION_IVAR = :@posthog_active_job_exception_captured
|
|
24
|
+
WEB_CAPTURED_EXCEPTION_IVAR = :@posthog_web_exception_captured
|
|
24
25
|
|
|
25
26
|
private_constant :ACTIVE_JOB_CAPTURED_EXCEPTION_IVAR
|
|
27
|
+
private_constant :WEB_CAPTURED_EXCEPTION_IVAR
|
|
26
28
|
|
|
27
29
|
class << self
|
|
28
30
|
# @return [PostHog::Rails::Configuration] Rails integration configuration.
|
|
@@ -85,6 +87,42 @@ module PostHog
|
|
|
85
87
|
rescue StandardError
|
|
86
88
|
false
|
|
87
89
|
end
|
|
90
|
+
|
|
91
|
+
# Mark an exception as already captured by the CaptureExceptions middleware.
|
|
92
|
+
#
|
|
93
|
+
# ActionDispatch::Executor sits above our middleware and reports unhandled
|
|
94
|
+
# exceptions to Rails.error *after* the response has unwound back through
|
|
95
|
+
# CaptureExceptions, so `in_web_request?` is already false by then. The mark
|
|
96
|
+
# lets ErrorSubscriber recognize the report as a duplicate.
|
|
97
|
+
#
|
|
98
|
+
# The whole cause chain is marked because ActionDispatch::ExceptionWrapper
|
|
99
|
+
# unwraps ActionView::Template::Error to its cause, meaning Rails can report
|
|
100
|
+
# a different object than the one the middleware captured.
|
|
101
|
+
# @api private
|
|
102
|
+
# @param exception [Exception]
|
|
103
|
+
# @return [void]
|
|
104
|
+
def mark_web_exception_captured(exception)
|
|
105
|
+
current = exception
|
|
106
|
+
seen = {}.compare_by_identity
|
|
107
|
+
|
|
108
|
+
while current.is_a?(Exception) && !seen[current]
|
|
109
|
+
seen[current] = true
|
|
110
|
+
current.instance_variable_set(WEB_CAPTURED_EXCEPTION_IVAR, true)
|
|
111
|
+
current = current.cause
|
|
112
|
+
end
|
|
113
|
+
rescue StandardError
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Check whether an exception was already captured by CaptureExceptions.
|
|
118
|
+
# @api private
|
|
119
|
+
# @param exception [Exception]
|
|
120
|
+
# @return [Boolean]
|
|
121
|
+
def web_exception_captured?(exception)
|
|
122
|
+
exception.instance_variable_get(WEB_CAPTURED_EXCEPTION_IVAR) == true
|
|
123
|
+
rescue StandardError
|
|
124
|
+
false
|
|
125
|
+
end
|
|
88
126
|
end
|
|
89
127
|
end
|
|
90
128
|
end
|