debugbundle 1.1.0 → 1.1.2

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: 55cf00eddb0f7fc23cdc0b574d5c8c95f1b06575dfcef315e7c8f5c31278942b
4
- data.tar.gz: 43e388045674fc42d1cc44f11365cb392aae7f3a09f64f3784c776cd96c79b6f
3
+ metadata.gz: 2233153d82d41df1121182d5e7f217f02c4b1a0c7348386505c0406e09db3e86
4
+ data.tar.gz: d1b0169d3968aa5c11a2eda1751bf9612afa63109818359d48e7ab1f94384c49
5
5
  SHA512:
6
- metadata.gz: e0beea973c239fdbe571ffbe9e62f48e206112414b9372466e6c99252bd4ed85dc6c349bed7986875d04b77d8e8a6525e35d9fcd3291b8066ffa60fad4d0d73a
7
- data.tar.gz: 374744696cbd5d1cf8b05791ac67e9e275e33c88fa4d1d3e363056db7b44f3e225fff2c60d223ff4508440e69ec32ab045eb7d9271daea7601d7d758ec6c0569
6
+ metadata.gz: 279871a9cf53e67fbbd269eaddc86c6003428993729d81c1b6586aa787780687c29b8a602716cbad9e1f33ca829564a9b936aaad282611c6594e66073d2654d1
7
+ data.tar.gz: 6b3b419131b880e0073322aff591c8dabfb5343374331246504b99fb31e1deeb1e79c17769c8a2ce7ad4288b81c186e0d0cd63eaa1ac631a709d13659f0f3554
data/README.md CHANGED
@@ -314,7 +314,7 @@ This repository also ships a clean-install app-driven smoke harness that validat
314
314
 
315
315
  ```sh
316
316
  make smoke
317
- make smoke-published VERSION=1.1.0
317
+ make smoke-published VERSION=1.1.2
318
318
  ```
319
319
 
320
320
  `make smoke` builds the gem, installs it into a fresh RubyGems home, drives a Rack request plus a browser relay batch through the public SDK surface, validates event envelope shape, and confirms the mock ingestion endpoint receives the expected service, environment, SDK metadata, and correlation fields.
@@ -41,9 +41,7 @@ module DebugBundle
41
41
  class << self
42
42
  attr_accessor :thread_exception_client
43
43
 
44
- def dispatch_thread_exception(error)
45
- thread_exception_client&.__send__(:capture_thread_exception, error)
46
- end
44
+ def dispatch_thread_exception(error) = thread_exception_client&.__send__(:capture_thread_exception, error)
47
45
 
48
46
  def install_thread_exception_hook!
49
47
  THREAD_HOOK_MUTEX.synchronize do
@@ -128,18 +126,17 @@ module DebugBundle
128
126
  }
129
127
 
130
128
  causes = exception_causes(error)
131
- payload['causes'] = causes unless causes.empty?
132
129
 
133
130
  probe_data = probe_snapshot
134
131
  payload['probe_data'] = probe_data unless probe_data.empty?
135
132
 
136
133
  extra_context = merged_context.except('request', 'response', 'correlation')
137
- payload['context'] = extra_context unless extra_context.empty?
134
+ extra_context['causes'] = causes unless causes.empty?
138
135
 
139
136
  suppression_key = [payload['name'], payload['message'], payload['stack']].join(':')
140
137
  return unless @suppression.should_capture(suppression_key, now: monotonic_now)
141
138
 
142
- enqueue_event(base_event('backend_exception', payload, merged_context))
139
+ enqueue_event(base_event('backend_exception', payload, extra_context))
143
140
  end
144
141
 
145
142
  def capture_error(error, context: nil, handled: true) = capture_exception(error, context: context, handled: handled)
@@ -181,8 +178,6 @@ module DebugBundle
181
178
  'response_status' => response_status,
182
179
  'duration_ms' => extract_duration_ms(merged_context, sanitized_response),
183
180
  'route_template' => merged_context['route_template'],
184
- 'controller' => merged_context['controller'],
185
- 'action' => merged_context['action'],
186
181
  'response_headers' => sanitized_response['headers'],
187
182
  'response_body' => sanitized_response['body']
188
183
  }
@@ -414,8 +409,8 @@ module DebugBundle
414
409
  def request_payload(request)
415
410
  source = object_to_hash(request)
416
411
  {
417
- 'method' => source['method'],
418
- 'path' => source['path'],
412
+ 'method' => source['method'] || 'UNKNOWN',
413
+ 'path' => source['path'] || '/',
419
414
  'query' => @redactor.redact_value(source['query'] || {}),
420
415
  'headers' => sanitized_headers(source['headers'] || {}),
421
416
  'body' => @redactor.redact_value(source['body'] || {})
@@ -494,7 +489,7 @@ module DebugBundle
494
489
  end
495
490
 
496
491
  def base_event(event_type, payload, context)
497
- {
492
+ event = {
498
493
  'schema_version' => SCHEMA_VERSION,
499
494
  'event_id' => SecureRandom.uuid,
500
495
  'event_type' => event_type,
@@ -511,6 +506,9 @@ module DebugBundle
511
506
  'correlation' => correlation_payload(context),
512
507
  'payload' => @redactor.redact_value(payload)
513
508
  }
509
+ envelope_context = event_context(context)
510
+ event['context'] = envelope_context unless envelope_context.empty?
511
+ event
514
512
  end
515
513
 
516
514
  def service_name = config.service || DEFAULT_SERVICE_NAME
@@ -528,6 +526,18 @@ module DebugBundle
528
526
  }
529
527
  end
530
528
 
529
+ def event_context(context)
530
+ object_to_hash(context).except(
531
+ 'request',
532
+ 'response',
533
+ 'correlation',
534
+ 'request_id',
535
+ 'trace_id',
536
+ 'session_id',
537
+ 'user_id_hash'
538
+ )
539
+ end
540
+
531
541
  def object_to_hash(value)
532
542
  case value
533
543
  when Hash
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DebugBundle
4
- VERSION = '1.1.0'
4
+ VERSION = '1.1.2'
5
5
  end
@@ -57,11 +57,16 @@
57
57
  "event_id": { "type": "string", "format": "uuid" },
58
58
  "event_type": { "type": "string", "minLength": 1 },
59
59
  "project_token": { "type": "string", "minLength": 1 },
60
+ "project_id": { "type": ["string", "null"], "format": "uuid" },
60
61
  "sdk_name": { "type": "string", "minLength": 1 },
61
62
  "sdk_version": { "type": "string", "minLength": 1 },
62
63
  "service": { "$ref": "#/$defs/service" },
63
64
  "occurred_at": { "type": "string", "format": "date-time" },
64
65
  "correlation": { "$ref": "#/$defs/correlation" },
66
+ "context": {
67
+ "type": "object",
68
+ "additionalProperties": true
69
+ },
65
70
  "payload": {}
66
71
  }
67
72
  },
@@ -195,10 +195,14 @@ RSpec.describe DebugBundle::Rack::Middleware do
195
195
  )
196
196
 
197
197
  client.flush
198
- payload = transport_events.fetch(0).fetch(:events).fetch(0).fetch('payload')
198
+ event = transport_events.fetch(0).fetch(:events).fetch(0)
199
+ payload = event.fetch('payload')
200
+ context = event.fetch('context')
199
201
 
200
202
  expect(payload).to include(
201
- 'route_template' => '/patients/:patient_id/checkouts',
203
+ 'route_template' => '/patients/:patient_id/checkouts'
204
+ )
205
+ expect(context).to include(
202
206
  'controller' => 'checkouts',
203
207
  'action' => 'create'
204
208
  )
@@ -50,7 +50,7 @@ if defined?(Sidekiq)
50
50
 
51
51
  expect(event.fetch('event_type')).to eq('backend_exception')
52
52
  expect(event.fetch('correlation')).to include('trace_id' => 'trace-chain-1')
53
- expect(event.fetch('payload').fetch('context').fetch('job')).to include(
53
+ expect(event.fetch('context').fetch('job')).to include(
54
54
  'class' => 'CheckoutWorker',
55
55
  'queue' => 'critical',
56
56
  'jid' => 'jid-chain-1'
@@ -40,7 +40,7 @@ RSpec.describe DebugBundle::Sidekiq::ServerMiddleware do
40
40
 
41
41
  expect(event.fetch('event_type')).to eq('backend_exception')
42
42
  expect(event.fetch('correlation')).to include('trace_id' => 'trace-job-1')
43
- expect(event.fetch('payload').fetch('context').fetch('job')).to include(
43
+ expect(event.fetch('context').fetch('job')).to include(
44
44
  'class' => 'CheckoutWorker',
45
45
  'queue' => 'critical',
46
46
  'jid' => 'jid-1',
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debugbundle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - DebugBundle
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-06-08 00:00:00.000000000 Z
10
+ date: 2026-06-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: base64