clamp-analytics 0.1.0 → 0.2.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: ffb1d4e3b88c1a033a823f87ca944677956ba43bb9899f17904d4e9009e14998
4
- data.tar.gz: '046796aafe3d755145de3304ee15d9ca4210a90d1aa3706b1578c07d94eb797e'
3
+ metadata.gz: 1c17e252fdceaf3760f959252b2ac2196a03c3980b7d95d017a3021f72620fa4
4
+ data.tar.gz: 7e351406203ac370254d7ca34e2fd2fe323fa44bd21d9608c8734b7dc32fddf2
5
5
  SHA512:
6
- metadata.gz: 5deb502c2bfa8ec1007c11cfb93e736dfd933e216ea4d9bc3c6f580d0da7b5d9575f58ac54ea28ecec069f1adb61e9a59e258c4f7054dd239c230ebc823ad10b
7
- data.tar.gz: 57be92f93a604ebea4f33c4ca526fd89bd57866fbee0ea9d705cf7bd6c3eafb613e5337b66f9de6651f5af29bd4330de37831f4703bc536f686b10a8b106c3fd
6
+ metadata.gz: 30a8aabb56447212110845cadc9e618b4787a4d41c879ae7e3807ece111f61fff5c73eed60e5d04d3cb515c936e8c556c3c210bdd0a186917fcc09497709daeb
7
+ data.tar.gz: c0a0debb406622311a582cd8cb17b94a8c9e2871d577ffcdf8492426a1f9880c11a034aca35159cafc56e6f7ac44c05ce8702cc63af2ff892701fe334603e581
data/README.md CHANGED
@@ -73,6 +73,25 @@ Clamp::Analytics::Money.new(29.00, "USD")
73
73
 
74
74
  A typed monetary value. `amount` is in major units (29.00, not 2900). `currency` is an ISO 4217 code (uppercase, three letters).
75
75
 
76
+ ### `Clamp::Analytics.capture_error(exception, context: {}, anonymous_id: nil, timestamp: nil)`
77
+
78
+ Sends an exception as a `$error` event. Convenience over `track` that extracts message, class name, and backtrace from the exception. The server adds a stable fingerprint at ingest so the same bug groups across occurrences.
79
+
80
+ ```ruby
81
+ begin
82
+ process_webhook(payload)
83
+ rescue => e
84
+ Clamp::Analytics.capture_error(e, context: { webhook: "stripe" })
85
+ end
86
+ ```
87
+
88
+ - **`exception`**: any `Exception` instance. Stack via `exception.backtrace`, type via `exception.class.name`.
89
+ - **`context`**: optional flat hash of additional properties. Values must be primitives (`String`, `Integer`, `Float`, `true`/`false`); the reserved key `:handled` is ignored.
90
+ - **`anonymous_id`**: optional. Links the error to a browser visitor.
91
+ - **`timestamp`**: optional `Time` or ISO 8601 string.
92
+
93
+ Same return value and exceptions as `track`. Lengths are capped (`error.message` 1KB, `error.type` 64 chars, `error.stack` 16KB) to match server-side limits.
94
+
76
95
  ## Framework integrations
77
96
 
78
97
  Per-framework integration patterns (Rails initializer + concern, Sinatra helper, Sidekiq middleware) are documented at <https://clamp.sh/docs/sdk/ruby>.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Clamp
4
4
  module Analytics
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -73,6 +73,49 @@ module Clamp
73
73
  true
74
74
  end
75
75
 
76
+ # Capture an exception as a `$error` event. Convenience wrapper that
77
+ # extracts message/type/backtrace from the exception and forwards to
78
+ # {.track}. The server adds a stable fingerprint at ingest so the same
79
+ # bug groups across occurrences.
80
+ #
81
+ # begin
82
+ # process_webhook(payload)
83
+ # rescue => e
84
+ # Clamp::Analytics.capture_error(e, context: { webhook: "stripe" })
85
+ # end
86
+ #
87
+ # @param exception [Exception] the exception to capture
88
+ # @param context [Hash] optional flat hash of additional properties.
89
+ # Values must be primitives (String, Integer, Float, true/false).
90
+ # The reserved key `:handled` is ignored if present.
91
+ # @param anonymous_id [String, nil] optional, links to a browser visitor
92
+ # @param timestamp [Time, String, nil] optional
93
+ # @raise [NotInitializedError] if init has not been called
94
+ # @raise [HTTPError] on non-2xx response
95
+ # @return [true]
96
+ def capture_error(exception, context: {}, anonymous_id: nil, timestamp: nil)
97
+ message = (exception.message || "Unknown error")[0, 1024]
98
+ error_type = exception.class.name[0, 64]
99
+ backtrace = (exception.backtrace || []).join("\n")
100
+ stack = backtrace.empty? ? "" : backtrace[0, 16384]
101
+
102
+ properties = {
103
+ "error.message" => message,
104
+ "error.type" => error_type,
105
+ "error.stack" => stack,
106
+ "error.handled" => true
107
+ }
108
+ context.each do |k, v|
109
+ key = k.to_s
110
+ next if key == "handled"
111
+ if v.is_a?(String) || v.is_a?(Integer) || v.is_a?(Float) || v == true || v == false
112
+ properties[key] = v
113
+ end
114
+ end
115
+
116
+ track("$error", properties: properties, anonymous_id: anonymous_id, timestamp: timestamp)
117
+ end
118
+
76
119
  # Override the transport. Used by tests; pass nil to restore the default.
77
120
  def transport=(transport)
78
121
  @mutex.synchronize { @transport = transport }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clamp-analytics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clamp Analytics
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-30 00:00:00.000000000 Z
11
+ date: 2026-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec