hawk-ruby 0.1.1 → 0.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +14 -13
  4. data/docs/api.md +25 -0
  5. data/docs/integrations.md +12 -20
  6. data/docs/releasing.md +3 -3
  7. data/lib/hawk/boundary.rb +1 -0
  8. data/lib/hawk/breadcrumbs/logger.rb +1 -0
  9. data/lib/hawk/breadcrumbs/net_http.rb +1 -0
  10. data/lib/hawk/breadcrumbs/rails.rb +1 -0
  11. data/lib/hawk/breadcrumbs.rb +1 -0
  12. data/lib/hawk/client.rb +96 -2
  13. data/lib/hawk/configuration.rb +197 -8
  14. data/lib/hawk/delayed_job.rb +2 -1
  15. data/lib/hawk/delivery.rb +1 -0
  16. data/lib/hawk/diagnostics.rb +8 -0
  17. data/lib/hawk/event.rb +1 -0
  18. data/lib/hawk/filter.rb +1 -0
  19. data/lib/hawk/filtered_fields.rb +1 -0
  20. data/lib/hawk/framework_filter.rb +1 -0
  21. data/lib/hawk/hook.rb +1 -0
  22. data/lib/hawk/integrations.rb +16 -0
  23. data/lib/hawk/job_context.rb +1 -0
  24. data/lib/hawk/json_value.rb +1 -0
  25. data/lib/hawk/process_hooks.rb +1 -0
  26. data/lib/hawk/rack/body.rb +1 -0
  27. data/lib/hawk/rack.rb +15 -1
  28. data/lib/hawk/rails/action_cable.rb +1 -0
  29. data/lib/hawk/rails/active_job.rb +1 -0
  30. data/lib/hawk/rails/error_subscriber.rb +1 -0
  31. data/lib/hawk/rails/integration.rb +1 -3
  32. data/lib/hawk/rails/payload_filter.rb +1 -0
  33. data/lib/hawk/rake.rb +2 -1
  34. data/lib/hawk/release.rb +1 -0
  35. data/lib/hawk/resque.rb +2 -1
  36. data/lib/hawk/scope.rb +25 -1
  37. data/lib/hawk/scope_store.rb +1 -0
  38. data/lib/hawk/sidekiq.rb +2 -1
  39. data/lib/hawk/source.rb +1 -0
  40. data/lib/hawk/token.rb +2 -0
  41. data/lib/hawk/transport.rb +1 -0
  42. data/lib/hawk/version.rb +3 -1
  43. data/lib/hawk-ruby.rb +3 -0
  44. data/lib/hawk.rb +51 -2
  45. data/sig/hawk/integrations.rbs +3 -0
  46. metadata +5 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9a71442090adcd7b76fdf5ea4de73e23c32dd4fd1d2c16320b6bea56cb8f729
4
- data.tar.gz: 3a5be0475ee73759a6413a7ab1883892a08562c2f683bd1f5973276aab542207
3
+ metadata.gz: 6567a3e5fc62ed4b72b2b03e1510158c6647018a5cf76e5ed3c1e4c500ff79b4
4
+ data.tar.gz: 5f75aa16ce1cff05c46fd68f0f0e315572c8924dabd9be8816d883ed0056ce22
5
5
  SHA512:
6
- metadata.gz: 7eb5a415bc25de6ecbb8febc98d950dcc1a7af93efaf62d54ca3b00edd9a18933c8b0b4a5f0de3631c80f362df19704d48f23770f738e0576e4223ff8bad62d2
7
- data.tar.gz: 9fd1d563a3e681d6919d18cc505b755a0b9469d8fc90fc2e66bc97f8a7466e4a145da2a1e2678c305f444a8cb6f433390115bc58bed3524e3c4a24c68496d276
6
+ metadata.gz: 800b94ebf049946ee15db9436f7297d971113d7976eb57eeda80ba3a2aeebeab8f20d219edc5dac1d19816753737f23cfc2f32227df69925bcd25f88f3de0763
7
+ data.tar.gz: 163ff6fc81f90b47ff0cb8431dbfd4dbe2249bcde6e6f2824e94de7afa9ef0d39b365afa0ee816a6ff37cbdcba0cf20f5202fa7a8ae9a6bcf3c5e4f6fc926ed3
data/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ Versions follow [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html)
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.2] - 2026-10-30
10
+
11
+ ### Added
12
+
13
+ - Support standard Bundler loading without a custom `require:` option.
14
+ - Detect loaded Rails, Rake, Sidekiq, Resque, and Delayed Job integrations during startup.
15
+
9
16
  ## [0.1.1] - 2026-10-29
10
17
 
11
18
  ### Added
@@ -30,6 +37,7 @@ Initial release of the Hawk Ruby error reporting gem.
30
37
  - Provide bounded asynchronous delivery, execution-local scopes, duplicate suppression, fork recovery, privacy filters, and event hooks.
31
38
  - Ship RBS signatures and enforce complete type coverage, 100% line and branch coverage, and measured CRAP scores no greater than 10.
32
39
 
33
- [Unreleased]: https://github.com/svyatov/hawk.ruby/compare/v0.1.1...HEAD
40
+ [Unreleased]: https://github.com/svyatov/hawk.ruby/compare/v0.1.2...HEAD
41
+ [0.1.2]: https://github.com/svyatov/hawk.ruby/compare/v0.1.1...v0.1.2
34
42
  [0.1.1]: https://github.com/svyatov/hawk.ruby/compare/v0.1.0...v0.1.1
35
43
  [0.1.0]: https://github.com/svyatov/hawk.ruby/releases/tag/v0.1.0
data/README.md CHANGED
@@ -12,13 +12,13 @@ Ruby error reporting for [Hawk](https://hawk.so), with optional Rails and backgr
12
12
  Run this command from your application's directory, which must contain a Gemfile:
13
13
 
14
14
  ```sh
15
- bundle add hawk-ruby --version "~> 0.1.1" --require hawk
15
+ bundle add hawk-ruby --version "~> 0.1.2"
16
16
  ```
17
17
 
18
18
  Copy the integration token from your Hawk project into `HAWK_TOKEN`. Save this example as `report.rb`:
19
19
 
20
20
  ```ruby
21
- require "hawk"
21
+ require "hawk-ruby"
22
22
 
23
23
  Hawk.init do |config|
24
24
  config.token = ENV.fetch("HAWK_TOKEN")
@@ -47,24 +47,24 @@ A missing or empty token disables reporting. A malformed nonempty token raises `
47
47
 
48
48
  ## Rails and background jobs
49
49
 
50
- Use `require: "hawk/rails"` in your Gemfile for Rails. Initialize Hawk in `config/initializers/hawk.rb` before workers start.
51
-
52
- Rails enables request capture, `Rails.error`, Action Cable, Active Job, and safe notification breadcrumbs. Solid Queue works through Active Job.
53
-
54
- Add the relevant adapter requires to your application's startup file:
50
+ Use the standard Gemfile entry without a `require:` option. Initialize Hawk in `config/initializers/hawk.rb` before workers start:
55
51
 
56
52
  ```ruby
57
- require "hawk/rack"
58
- require "hawk/rake"
59
- require "hawk/sidekiq"
60
- require "hawk/resque"
61
- require "hawk/delayed_job"
53
+ Hawk.init do |config|
54
+ config.token = ENV.fetch("HAWK_TOKEN")
55
+ end
62
56
  ```
63
57
 
64
- Rails also detects loaded job backends during initialization. The adapters preserve native retries, arguments, and failure storage.
58
+ Rails enables request capture, `Rails.error`, Action Cable, Active Job, and safe notification breadcrumbs. Solid Queue works through Active Job.
59
+
60
+ Hawk automatically detects loaded Rails, Rake, Sidekiq, Resque, and Delayed Job integrations during startup. Load application dependencies before calling `Hawk.init`. No adapter requires are needed.
61
+
62
+ For a standalone Rack application, add `use Hawk::Rack` to `config.ru`. Rails inserts this middleware automatically. The adapters preserve native retries, arguments, and failure storage.
65
63
 
66
64
  See [integrations](docs/integrations.md) for placement, supported versions, propagation limits, and exclusions.
67
65
 
66
+ See [configuration](docs/configuration.md) for settings and [API documentation](CONTRIBUTING.md#api-documentation) to build the YARD reference.
67
+
68
68
  ## Delivery and privacy
69
69
 
70
70
  The default client uses one background thread and a queue of 100 events. Capture never waits for queue space. Each delivery makes one bounded HTTP attempt.
@@ -79,6 +79,7 @@ Source snippets are enabled within configured source roots. Set `send_source = f
79
79
 
80
80
  ```sh
81
81
  bundle exec rake check:fast
82
+ bundle exec rake check:docs
82
83
  bundle exec rake check:coverage
83
84
  bundle exec rake check:crap
84
85
  bundle exec rake check:audit
data/docs/api.md ADDED
@@ -0,0 +1,25 @@
1
+ # Hawk Ruby API
2
+
3
+ Hawk Ruby reports exceptions and messages to Hawk. Start with {Hawk} for the default client or {Hawk::Client} for independent project clients.
4
+
5
+ ```ruby
6
+ require "hawk"
7
+
8
+ Hawk.init { |config| config.token = ENV.fetch("HAWK_TOKEN") }
9
+ Hawk.capture_message("Checkout completed", context: { order_id: "42" })
10
+ Hawk.close(timeout: 5.0)
11
+ ```
12
+
13
+ Capture IDs confirm local acceptance. They do not confirm receipt by Hawk. Flush and close wait for delivery attempts, including failed attempts.
14
+
15
+ ## Reference
16
+
17
+ - {Hawk::Configuration} documents settings, types, and defaults.
18
+ - {Hawk::Scope} holds context and user data for an execution.
19
+ - {Hawk::Diagnostics} exposes delivery and filtering counters.
20
+ - {Hawk::Rack} captures request and response-body exceptions.
21
+ - {Hawk::ConfigurationError} identifies invalid configuration.
22
+
23
+ See the {file:docs/configuration.md configuration guide} for privacy, delivery, and hook behavior. See the {file:docs/integrations.md integration guide} for Rails and background jobs.
24
+
25
+ Methods marked `@api private` support the implementation and are omitted from this reference. Their Ruby visibility does not make them supported extension points.
data/docs/integrations.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Integrations
2
2
 
3
- Load optional adapters before workers start. Keep their framework gems in the application's Gemfile.
3
+ Keep framework gems in the application's Gemfile. Hawk detects loaded frameworks when it loads and when you call `Hawk.init`.
4
+
5
+ Load application dependencies before initializing Hawk, and initialize before workers start. Frameworks loaded after initialization are not automatically detected. Hawk does not load unused frameworks.
6
+
7
+ Use `gem "hawk-ruby"` without a `require:` option. Explicit `require "hawk"` and adapter-specific requires remain supported for existing applications.
4
8
 
5
9
  ## Supported versions
6
10
 
@@ -22,7 +26,7 @@ The adapters guard their supported framework versions. Resque activation require
22
26
  ## Rack
23
27
 
24
28
  ```ruby
25
- require "hawk/rack"
29
+ require "hawk-ruby"
26
30
 
27
31
  Hawk.init { |config| config.token = ENV.fetch("HAWK_TOKEN") }
28
32
  use Hawk::Rack
@@ -39,7 +43,7 @@ Use `Hawk::Rack.new(app, client: other_client)` for an independent project clien
39
43
 
40
44
  ## Rails requests and framework reports
41
45
 
42
- Use `require: "hawk/rails"` in your Gemfile. The Railtie inserts Hawk inside `ActionDispatch::DebugExceptions`.
46
+ Rails loads Hawk through Bundler without a custom `require:` option. The Railtie inserts Hawk inside `ActionDispatch::DebugExceptions`.
43
47
 
44
48
  ```ruby
45
49
  # config/initializers/hawk.rb
@@ -50,7 +54,7 @@ Hawk.init do |config|
50
54
  end
51
55
  ```
52
56
 
53
- If Rails is already loaded, requiring `hawk` also discovers its Railtie. Rails filtering runs before the application's `before_send` hook.
57
+ Load Hawk during Rails boot, before application initialization. Rails filtering runs before the application's `before_send` hook.
54
58
 
55
59
  The subscriber records explicit `Rails.error.report` calls, including handled errors and severity. Request dispatch reports share ownership with middleware to prevent duplicates.
56
60
 
@@ -92,9 +96,7 @@ Solid Queue uses this same Active Job contract. Tests exercise its database-back
92
96
 
93
97
  ## Sidekiq
94
98
 
95
- ```ruby
96
- require "hawk/sidekiq"
97
- ```
99
+ Hawk automatically activates the adapter when Sidekiq is loaded before Hawk initialization.
98
100
 
99
101
  Client middleware adds versioned context under a separate top-level `hawk` field. Server middleware starts an execution scope.
100
102
 
@@ -106,9 +108,7 @@ The adapter retains native payload arguments and retry behavior. Raw arguments r
106
108
 
107
109
  ## Resque
108
110
 
109
- ```ruby
110
- require "hawk/resque"
111
- ```
111
+ Hawk automatically activates the adapter when Resque is loaded before Hawk initialization.
112
112
 
113
113
  The adapter wraps job execution and delegates failure creation to the configured backend. Failed constantization and other failures before execution reach that backend path.
114
114
 
@@ -120,11 +120,7 @@ Active Job wrappers retain their own serialized context. Raw direct arguments re
120
120
 
121
121
  ## Delayed Job
122
122
 
123
- ```ruby
124
- require "hawk/delayed_job"
125
- ```
126
-
127
- Load the adapter before starting a worker. Its plugin observes perform, error, and failure callbacks, including handler deserialization failures.
123
+ Hawk automatically activates the adapter when Delayed Job is loaded before Hawk initialization. Its plugin observes perform, error, and failure callbacks, including handler deserialization failures.
128
124
 
129
125
  Native attempts, retry times, and terminal failure state remain unchanged. Direct job YAML and database columns remain unchanged.
130
126
 
@@ -132,11 +128,7 @@ Active Job wrappers carry their own versioned context. Direct jobs start fresh s
132
128
 
133
129
  ## Rake and process shutdown
134
130
 
135
- ```ruby
136
- require "hawk/rake"
137
- ```
138
-
139
- The Rake adapter reports escaping task failures and retains original task behavior. Nested task failures share automatic-report ownership.
131
+ Hawk automatically activates the adapter when Rake is loaded before Hawk initialization. The adapter reports escaping task failures and retains original task behavior. Nested task failures share automatic-report ownership.
140
132
 
141
133
  Core initialization installs one process exit hook when `global_errors` is enabled. It reports eligible uncaught main-process errors and attempts a bounded drain.
142
134
 
data/docs/releasing.md CHANGED
@@ -9,11 +9,11 @@ The workflow builds the gem once, inventories its packaged files and external ru
9
9
  To cut a version:
10
10
 
11
11
  1. Update the version, changelog, and installation example. Run the checks and merge to `main`.
12
- 2. Create a signed version tag, for example `git tag -s v0.1.1 -m 'Release 0.1.1'`.
13
- 3. Push the tag with `git push origin v0.1.1` and monitor the Release workflow.
12
+ 2. Create a signed version tag, for example `git tag -s v0.1.2 -m 'Release 0.1.2'`.
13
+ 3. Push the tag with `git push origin v0.1.2` and monitor the Release workflow.
14
14
  4. Review the successful build and approve the `release` environment deployment.
15
15
 
16
- To verify downloaded release assets, run `gh attestation verify hawk-ruby-0.1.1.gem --repo svyatov/hawk.ruby --signer-workflow svyatov/hawk.ruby/.github/workflows/release.yml`, then repeat for `sbom.cdx.json`. Run `sha256sum --check SHA256SUMS` from the download directory. RubyGems serves its gem attestation at `https://rubygems.org/api/v1/attestations/hawk-ruby-0.1.1.json`.
16
+ To verify downloaded release assets, run `gh attestation verify hawk-ruby-0.1.2.gem --repo svyatov/hawk.ruby --signer-workflow svyatov/hawk.ruby/.github/workflows/release.yml`, then repeat for `sbom.cdx.json`. Run `sha256sum --check SHA256SUMS` from the download directory. RubyGems serves its gem attestation at `https://rubygems.org/api/v1/attestations/hawk-ruby-0.1.2.json`.
17
17
 
18
18
  ## Recover a partial publication
19
19
 
data/lib/hawk/boundary.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Hawk
4
4
  # Adapters share report ownership while retaining their own execution scopes.
5
+ # @api private
5
6
  module Boundary
6
7
  def self.run(client, kind:, metadata:, inherit: false, &block)
7
8
  client.with_boundary(kind: kind, metadata: metadata, inherit: inherit) do
@@ -3,6 +3,7 @@
3
3
  require "logger"
4
4
 
5
5
  module Hawk
6
+ # @api private
6
7
  module Breadcrumbs
7
8
  # Logger keeps control of level filtering and lazy block evaluation.
8
9
  module Logger
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hawk
4
+ # @api private
4
5
  module Breadcrumbs
5
6
  # Guard Net::HTTP's internal recursion while retaining the response block API.
6
7
  module NetHTTP
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hawk
4
+ # @api private
4
5
  module Breadcrumbs
5
6
  # Notification payloads are intentionally excluded from automatic breadcrumbs.
6
7
  module Rails
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Hawk
4
4
  # Breadcrumb buffers belong to scopes; instrumentation guards belong to fibers.
5
+ # @api private
5
6
  module Breadcrumbs
6
7
  def self.install(configuration)
7
8
  if configuration.breadcrumbs_logger || configuration.logger_error_level
data/lib/hawk/client.rb CHANGED
@@ -1,16 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hawk
4
- # Owns policy and scope state; delivery receives detached JSON strings.
4
+ # Reports events for one project with independent delivery and execution scopes.
5
+ #
6
+ # Use {.build} to construct a client with the standard transport.
7
+ # Capture methods isolate reporting failures from application control flow.
8
+ #
9
+ # @example Report to another project
10
+ # config = Hawk::Configuration.new
11
+ # config.token = ENV.fetch("OTHER_HAWK_TOKEN")
12
+ # client = Hawk::Client.build(config)
13
+ # client.capture_message("Import completed")
14
+ # client.close
5
15
  class Client
6
- attr_reader :configuration, :diagnostics
16
+ # @return [Configuration] validated settings; configure before building the client
17
+ attr_reader :configuration
7
18
 
19
+ # @return [Diagnostics] delivery and filtering counters
20
+ attr_reader :diagnostics
21
+
22
+ # Builds a client with the standard HTTP transport and delivery queue.
23
+ #
24
+ # @param configuration [Configuration] settings to validate and retain
25
+ # @return [Client]
26
+ # @raise [ConfigurationError] if configuration is invalid
8
27
  def self.build(configuration)
9
28
  diagnostics = Diagnostics.new(configuration.diagnostic_callback, logger: configuration.diagnostic_logger)
10
29
  delivery = Delivery.new(configuration, transport: Transport.new(configuration), diagnostics: diagnostics)
11
30
  new(configuration, delivery: delivery, diagnostics: diagnostics)
12
31
  end
13
32
 
33
+ # @api private
14
34
  def initialize(configuration, delivery:, diagnostics: nil)
15
35
  configuration.validate!
16
36
  configuration.release = Release.detect(configuration)
@@ -22,22 +42,47 @@ module Hawk
22
42
  @closed = false
23
43
  end
24
44
 
45
+ # @return [Scope] mutable scope for this client, thread, and fiber
25
46
  def current_scope
26
47
  @store.current
27
48
  end
28
49
 
50
+ # @return [Boolean] whether the client is open and enabled for this environment
29
51
  def enabled?
30
52
  !@closed && @configuration.enabled?
31
53
  end
32
54
 
55
+ # Merges values into the current scope, replacing matching top-level keys.
56
+ #
57
+ # Values are copied into bounded JSON data without calling custom serializers.
58
+ #
59
+ # @param context [Hash{String, Symbol => Object}] application context
60
+ # @return [void]
33
61
  def set_context(context)
34
62
  current_scope.set_context(context)
35
63
  end
36
64
 
65
+ # Replaces the current scope's user. A nil value clears the scoped user.
66
+ #
67
+ # @param user [Hash{String, Symbol => Object}, nil] user data; include an :id when available
68
+ # @return [void]
37
69
  def set_user(user)
38
70
  current_scope.set_user(user)
39
71
  end
40
72
 
73
+ # Runs a block with a copy of the current scope and restores its parent.
74
+ #
75
+ # Restoration also occurs when the block raises an exception.
76
+ #
77
+ # @yield [scope] temporary scope for this execution
78
+ # @yieldparam scope [Scope]
79
+ # @yieldreturn [Object] application result
80
+ # @return [Object] the block's result
81
+ # @example Attach temporary context
82
+ # client.with_scope do |scope|
83
+ # scope.set_context(order_id: "42")
84
+ # client.capture_message("Order accepted")
85
+ # end
41
86
  def with_scope
42
87
  previous = current_scope
43
88
  @store.replace(previous.copy)
@@ -48,6 +93,7 @@ module Hawk
48
93
  end
49
94
  end
50
95
 
96
+ # @api private
51
97
  def using_scope(scope)
52
98
  previous = current_scope
53
99
  @store.replace(scope.copy)
@@ -58,6 +104,7 @@ module Hawk
58
104
  end
59
105
  end
60
106
 
107
+ # @api private
61
108
  def with_boundary(kind:, metadata:, inherit: false)
62
109
  previous = current_scope
63
110
  @store.clear_escape unless previous.boundary
@@ -70,24 +117,59 @@ module Hawk
70
117
  end
71
118
  end
72
119
 
120
+ # Reports an exception with the current scope and per-event overrides.
121
+ #
122
+ # Manual calls can report the same exception more than once. Filtering,
123
+ # sampling, disabled capture, or delivery rejection can discard the event.
124
+ #
125
+ # @param exception [Exception] exception to report
126
+ # @param context [Hash{String, Symbol => Object}] values merged over scoped context
127
+ # @param user [Hash{String, Symbol => Object}, nil] per-event user; nil uses scope or configuration
128
+ # @param level [Symbol] severity attached to the event, normally :error
129
+ # @return [String, nil] local capture ID, or nil when the event is not accepted
130
+ # @note A capture ID does not confirm receipt by Hawk.
73
131
  def capture_exception(exception, context: {}, user: nil, level: :error)
74
132
  identifier = dispatch(exception: exception, context: context, user: user, level: level)
75
133
  current_scope.ledger.accept(exception, evict: !current_scope.boundary) if identifier
76
134
  identifier
77
135
  end
78
136
 
137
+ # Reports a message with the current scope and per-event overrides.
138
+ #
139
+ # @param message [String] event title
140
+ # @param context [Hash{String, Symbol => Object}] values merged over scoped context
141
+ # @param user [Hash{String, Symbol => Object}, nil] per-event user; nil uses scope or configuration
142
+ # @param level [Symbol] severity attached to the event, normally :info
143
+ # @return [String, nil] local capture ID, or nil when the event is not accepted
144
+ # @note A capture ID does not confirm receipt by Hawk.
79
145
  def capture_message(message, context: {}, user: nil, level: :info)
80
146
  dispatch(message: message, context: context, user: user, level: level)
81
147
  end
82
148
 
149
+ # Adds a filtered, timestamped breadcrumb to the current scope.
150
+ #
151
+ # Retains the most recent 50 entries. Hook failures discard the entry.
152
+ #
153
+ # @param entry [Hash{String, Symbol => Object}] fields such as :message and :category
154
+ # @return [void]
83
155
  def add_breadcrumb(entry)
84
156
  Breadcrumbs.add(self, entry)
85
157
  end
86
158
 
159
+ # Reports exceptions escaping a block and raises the same exception again.
160
+ #
161
+ # Inherits the current scope. Automatic reporting excludes normal process
162
+ # termination, including SystemExit, SignalException, and Interrupt.
163
+ #
164
+ # @yield application work to monitor
165
+ # @yieldreturn [Object] application result
166
+ # @return [Object] the block's result
167
+ # @raise [Exception] any exception raised by the block, after reporting when eligible
87
168
  def capture(&)
88
169
  Boundary.run(self, kind: :capture, metadata: {}, inherit: true, &)
89
170
  end
90
171
 
172
+ # @api private
91
173
  def report(exception, mechanism:, context: {}, level: :error, handled: false)
92
174
  return if normal_termination?(exception)
93
175
  return if mechanism == "request" && expected_request_error?(exception)
@@ -102,20 +184,32 @@ module Hawk
102
184
  addons: { "mechanism" => mechanism, "handled" => handled })
103
185
  end
104
186
 
187
+ # @api private
105
188
  def remember_escape(exception)
106
189
  @store.remember_escape(exception)
107
190
  end
108
191
 
192
+ # @api private
109
193
  def consume_escape(exception)
110
194
  @store.consume_escape(exception)
111
195
  end
112
196
 
197
+ # Waits for pending attempts, including attempts that fail.
198
+ #
199
+ # @param timeout [Numeric] deadline in seconds
200
+ # @return [Boolean] true if pending attempts finished; false on timeout or failure
201
+ # @note Success does not confirm receipt by Hawk.
113
202
  def flush(timeout: @configuration.flush_timeout)
114
203
  @delivery.flush(timeout: timeout)
115
204
  rescue StandardError
116
205
  false
117
206
  end
118
207
 
208
+ # Stops accepting events, clears this execution's scope, and drains delivery.
209
+ #
210
+ # @param timeout [Numeric] deadline in seconds
211
+ # @return [Boolean] true if shutdown finished; false on timeout or failure
212
+ # @note The client remains closed if shutdown times out.
119
213
  def close(timeout: @configuration.flush_timeout)
120
214
  @closed = true
121
215
  @store.clear