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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +14 -13
- data/docs/api.md +25 -0
- data/docs/integrations.md +12 -20
- data/docs/releasing.md +3 -3
- data/lib/hawk/boundary.rb +1 -0
- data/lib/hawk/breadcrumbs/logger.rb +1 -0
- data/lib/hawk/breadcrumbs/net_http.rb +1 -0
- data/lib/hawk/breadcrumbs/rails.rb +1 -0
- data/lib/hawk/breadcrumbs.rb +1 -0
- data/lib/hawk/client.rb +96 -2
- data/lib/hawk/configuration.rb +197 -8
- data/lib/hawk/delayed_job.rb +2 -1
- data/lib/hawk/delivery.rb +1 -0
- data/lib/hawk/diagnostics.rb +8 -0
- data/lib/hawk/event.rb +1 -0
- data/lib/hawk/filter.rb +1 -0
- data/lib/hawk/filtered_fields.rb +1 -0
- data/lib/hawk/framework_filter.rb +1 -0
- data/lib/hawk/hook.rb +1 -0
- data/lib/hawk/integrations.rb +16 -0
- data/lib/hawk/job_context.rb +1 -0
- data/lib/hawk/json_value.rb +1 -0
- data/lib/hawk/process_hooks.rb +1 -0
- data/lib/hawk/rack/body.rb +1 -0
- data/lib/hawk/rack.rb +15 -1
- data/lib/hawk/rails/action_cable.rb +1 -0
- data/lib/hawk/rails/active_job.rb +1 -0
- data/lib/hawk/rails/error_subscriber.rb +1 -0
- data/lib/hawk/rails/integration.rb +1 -3
- data/lib/hawk/rails/payload_filter.rb +1 -0
- data/lib/hawk/rake.rb +2 -1
- data/lib/hawk/release.rb +1 -0
- data/lib/hawk/resque.rb +2 -1
- data/lib/hawk/scope.rb +25 -1
- data/lib/hawk/scope_store.rb +1 -0
- data/lib/hawk/sidekiq.rb +2 -1
- data/lib/hawk/source.rb +1 -0
- data/lib/hawk/token.rb +2 -0
- data/lib/hawk/transport.rb +1 -0
- data/lib/hawk/version.rb +3 -1
- data/lib/hawk-ruby.rb +3 -0
- data/lib/hawk.rb +51 -2
- data/sig/hawk/integrations.rbs +3 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6567a3e5fc62ed4b72b2b03e1510158c6647018a5cf76e5ed3c1e4c500ff79b4
|
|
4
|
+
data.tar.gz: 5f75aa16ce1cff05c46fd68f0f0e315572c8924dabd9be8816d883ed0056ce22
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
13
|
-
3. Push the tag with `git push origin v0.1.
|
|
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.
|
|
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
|
data/lib/hawk/breadcrumbs.rb
CHANGED
data/lib/hawk/client.rb
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Hawk
|
|
4
|
-
#
|
|
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
|
-
|
|
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
|