Module: Dispatch::Rails
- Defined in:
- lib/dispatch-rails.rb,
lib/dispatch/rails/engine.rb,
lib/dispatch/rails/version.rb,
lib/dispatch/rails/reporter.rb,
lib/dispatch/rails/transport.rb,
lib/dispatch/rails/middleware.rb,
lib/dispatch/rails/rake_handler.rb,
lib/dispatch/rails/configuration.rb,
lib/dispatch/rails/event_builder.rb,
lib/dispatch/rails/error_subscriber.rb,
lib/dispatch/rails/response_annotator.rb,
lib/dispatch/rails/heartbeat_aggregator.rb,
lib/dispatch/rails/heartbeat_middleware.rb
Defined Under Namespace
Modules: RakeHandler, Reporter Classes: Configuration, Engine, ErrorSubscriber, EventBuilder, HeartbeatAggregator, HeartbeatMiddleware, Middleware, ResponseAnnotator, Transport
Constant Summary collapse
- VERSION =
"0.7.0".freeze
Class Method Summary collapse
-
.capture_exception(exception, env: nil, context: {}, level: "error") ⇒ Object
Manually report a handled exception, e.g.
- .configuration ⇒ Object
- .configure {|configuration| ... } ⇒ Object
-
.handle_at_exit(exception = nil) ⇒ Object
The at_exit body, extracted so it can be exercised in tests.
-
.ignored_exit_exception?(exception) ⇒ Boolean
Normal exits and SIGTERM-driven graceful shutdowns (deploys, scale-downs) are not crashes.
-
.install_at_exit_callback ⇒ Object
Process-exit safety net: report the exception that is killing the process (a crash during boot, a dying runner/script), then ship the in-progress heartbeat window and drain the transport queue so already-captured events survive the shutdown.
-
.report(description:, severity: nil, source: "api", metadata: {}, reporter: nil, correlation_id: nil) ⇒ Object
File a curated bug report (a ticket) programmatically — the API-only analogue of a human clicking the widget.
- .reset! ⇒ Object
Class Method Details
.capture_exception(exception, env: nil, context: {}, level: "error") ⇒ Object
Manually report a handled exception, e.g. inside a rescue:
rescue => e
Dispatch::Rails.capture_exception(e, context: { tags: { area: "import" } })
end
33 34 35 |
# File 'lib/dispatch-rails.rb', line 33 def capture_exception(exception, env: nil, context: {}, level: "error") Reporter.capture(exception, handled: true, env: env, context: context, level: level) end |
.configuration ⇒ Object
17 18 19 |
# File 'lib/dispatch-rails.rb', line 17 def configuration @configuration ||= Configuration.new end |
.configure {|configuration| ... } ⇒ Object
21 22 23 |
# File 'lib/dispatch-rails.rb', line 21 def configure yield(configuration) end |
.handle_at_exit(exception = nil) ⇒ Object
The at_exit body, extracted so it can be exercised in tests.
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/dispatch-rails.rb', line 76 def handle_at_exit(exception = nil) if exception && !ignored_exit_exception?(exception) && configuration.capture_at_exit Reporter.capture(exception, handled: false, context: { tags: { source: "at_exit" } }) end timeout = configuration.shutdown_timeout.to_f return unless timeout.positive? HeartbeatAggregator.instance.deliver_all Transport.instance.flush(timeout: timeout) end |
.ignored_exit_exception?(exception) ⇒ Boolean
Normal exits and SIGTERM-driven graceful shutdowns (deploys, scale-downs) are not crashes.
90 91 92 93 94 95 96 |
# File 'lib/dispatch-rails.rb', line 90 def ignored_exit_exception?(exception) return true if exception.is_a?(SystemExit) return false unless exception.is_a?(SignalException) name = exception.respond_to?(:signm) ? exception.signm.to_s : exception.to_s name.end_with?("TERM") end |
.install_at_exit_callback ⇒ Object
Process-exit safety net: report the exception that is killing the process (a crash during boot, a dying runner/script), then ship the in-progress heartbeat window and drain the transport queue so already-captured events survive the shutdown. Exceptions captured upstream (middleware, rake handler) carry the Reporter dedup marker and aren’t re-sent.
68 69 70 71 72 73 |
# File 'lib/dispatch-rails.rb', line 68 def install_at_exit_callback return if @at_exit_installed @at_exit_installed = true at_exit { handle_at_exit($!) } end |
.report(description:, severity: nil, source: "api", metadata: {}, reporter: nil, correlation_id: nil) ⇒ Object
File a curated bug report (a ticket) programmatically — the API-only analogue of a human clicking the widget. Ideal for an AI agent or a rescue block that wants to turn a failure into a tracked, human-readable report. Pass a correlation_id (e.g. request.request_id) to link the report to an already-captured error. Synchronous — returns the created ticket’s { “id”, “status”, “url” } Hash, or nil on failure. Never raises.
Dispatch::Rails.report(
description: "Nightly import aborted: upstream returned 502",
severity: "high",
correlation_id: request.request_id,
metadata: { job: "ImportJob" }
)
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/dispatch-rails.rb', line 50 def report(description:, severity: nil, source: "api", metadata: {}, reporter: nil, correlation_id: nil) return nil unless configuration.configured? = ( || {}).dup [:correlation_id] = correlation_id if correlation_id ticket = { description: description, source: source, severity: severity, metadata: , reporter: reporter }.compact Transport.instance.post_ticket(ticket: ticket) end |
.reset! ⇒ Object
25 26 27 |
# File 'lib/dispatch-rails.rb', line 25 def reset! @configuration = Configuration.new end |