Module: RailsInformant

Defined in:
lib/rails_informant.rb,
lib/rails_informant/event.rb,
lib/rails_informant/engine.rb,
lib/rails_informant/current.rb,
lib/rails_informant/version.rb,
lib/rails_informant/mcp/client.rb,
lib/rails_informant/mcp/server.rb,
lib/rails_informant/fingerprint.rb,
lib/rails_informant/configuration.rb,
lib/rails_informant/mcp/base_tool.rb,
app/jobs/rails_informant/purge_job.rb,
lib/rails_informant/context_filter.rb,
lib/rails_informant/error_recorder.rb,
app/jobs/rails_informant/notify_job.rb,
lib/rails_informant/context_builder.rb,
lib/rails_informant/notifiers/slack.rb,
lib/rails_informant/error_subscriber.rb,
app/models/rails_informant/occurrence.rb,
lib/rails_informant/breadcrumb_buffer.rb,
lib/rails_informant/mcp/configuration.rb,
lib/rails_informant/notifiers/webhook.rb,
app/models/rails_informant/error_group.rb,
lib/rails_informant/mcp/tools/get_error.rb,
app/jobs/rails_informant/application_job.rb,
lib/rails_informant/breadcrumb_subscriber.rb,
lib/rails_informant/mcp/tools/list_errors.rb,
lib/rails_informant/mcp/tools/delete_error.rb,
lib/rails_informant/mcp/tools/ignore_error.rb,
lib/rails_informant/mcp/tools/reopen_error.rb,
lib/rails_informant/mcp/tools/notify_deploy.rb,
lib/rails_informant/mcp/tools/resolve_error.rb,
lib/rails_informant/mcp/tools/annotate_error.rb,
lib/rails_informant/mcp/tools/mark_duplicate.rb,
lib/rails_informant/middleware/error_capture.rb,
app/models/rails_informant/application_record.rb,
lib/rails_informant/notifiers/circuit_breaker.rb,
lib/generators/rails_informant/skill_generator.rb,
lib/rails_informant/mcp/tools/list_occurrences.rb,
lib/rails_informant/mcp/tools/mark_fix_pending.rb,
lib/rails_informant/mcp/tools/list_environments.rb,
lib/rails_informant/structured_event_subscriber.rb,
lib/generators/rails_informant/install_generator.rb,
lib/rails_informant/notifiers/notification_policy.rb,
lib/rails_informant/mcp/tools/get_informant_status.rb,
lib/rails_informant/mcp/tools/verify_pending_fixes.rb,
app/controllers/rails_informant/api/base_controller.rb,
app/controllers/rails_informant/api/errors_controller.rb,
app/controllers/rails_informant/api/status_controller.rb,
app/controllers/rails_informant/api/deploys_controller.rb,
app/controllers/rails_informant/api/occurrences_controller.rb,
lib/rails_informant/middleware/rescued_exception_interceptor.rb

Defined Under Namespace

Modules: Api, Mcp, Middleware, Notifiers Classes: ApplicationJob, ApplicationRecord, BreadcrumbBuffer, BreadcrumbSubscriber, Configuration, ContextBuilder, ContextFilter, Current, Engine, ErrorGroup, ErrorRecorder, ErrorSubscriber, Event, Fingerprint, InstallGenerator, NotifyJob, Occurrence, PurgeJob, SkillGenerator, StructuredEventSubscriber

Constant Summary collapse

InvalidParameterError =
Class.new(StandardError)
NotifierError =
Class.new(StandardError)
IGNORED_EXCEPTIONS_DEFAULT =

Only exceptions that are noise in every context. Rails 8.1 maps HTTP client errors (404s, routing, bad params) via rescue_responses and never reports them to Rails.error on the request path, so listing them here was redundant for requests and wrongly suppressed the same exceptions when they are real bugs in background jobs (e.g. a job’s RecordNotFound). Those are recorded now; what remains is process-control and client/tamper noise.

%w[
  ActionController::UnknownAction
  CGI::Session::CookieStore::TamperedWithCookie
  Mime::Type::InvalidMimeType
  Rack::Utils::InvalidParameterError
  SignalException
  SystemExit
].freeze
GIT_SHA_SOURCES =
%w[GIT_SHA REVISION KAMAL_VERSION].freeze
SHA_FORMAT =
/\A[0-9a-f]{7,40}\z/i
VERSION =
ENV.fetch("RAILS_INFORMANT_VERSION", "0.0.0.dev")

Class Method Summary collapse

Class Method Details

.already_captured?(error) ⇒ Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/rails_informant.rb', line 111

def already_captured?(error)
  error.instance_variable_get(:@__rails_informant_captured)
end

.capture(exception, context: {}, request: nil) ⇒ Object



123
124
125
126
127
128
129
# File 'lib/rails_informant.rb', line 123

def capture(exception, context: {}, request: nil)
  return if Current.silenced
  return if ignored_exception?(exception)
  return if already_captured?(exception)
  mark_captured!(exception)
  ErrorRecorder.record exception, severity: "error", context:, env: request&.env
end

.configure {|config| ... } ⇒ Object

Yields:

  • (config)


65
66
67
68
# File 'lib/rails_informant.rb', line 65

def configure
  yield config
  reset_caches!
end

.console_mode?Boolean

Returns:

  • (Boolean)


135
136
137
# File 'lib/rails_informant.rb', line 135

def console_mode?
  defined?(Rails::Console)
end

.current_git_shaObject



107
108
109
# File 'lib/rails_informant.rb', line 107

def current_git_sha
  @_current_git_sha ||= resolve_git_sha
end

.ignored_exception?(exception) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rails_informant.rb', line 84

def ignored_exception?(exception)
  ignored = ignored_exception_set
  current = exception
  depth = 0
  while current && depth < ContextBuilder::MAX_CAUSE_DEPTH
    current.class.ancestors.each do |ancestor|
      name = ancestor.name or next
      return true if ignored.include?(name)
    end
    current = current.cause
    depth += 1
  end
  false
end

.ignored_path?(env) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
# File 'lib/rails_informant.rb', line 99

def ignored_path?(env)
  return false unless env
  paths = ignored_paths
  return false if paths.empty?
  request_path = env["PATH_INFO"]
  paths.any? { request_path == it || request_path&.start_with?("#{it}/") }
end

.initialized?Boolean

Returns:

  • (Boolean)


76
77
78
79
80
81
82
# File 'lib/rails_informant.rb', line 76

def initialized?
  return @_initialized if defined?(@_initialized) && @_initialized

  @_initialized = capture_errors && defined?(ActiveRecord::Base) && ActiveRecord::Base.connection_pool.with_connection { true }
rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::NoDatabaseError
  false
end

.mark_captured!(error) ⇒ Object



131
132
133
# File 'lib/rails_informant.rb', line 131

def mark_captured!(error)
  error.instance_variable_set(:@__rails_informant_captured, true) unless error.frozen?
end

.reset_caches!Object



70
71
72
73
74
# File 'lib/rails_informant.rb', line 70

def reset_caches!
  @_initialized = nil
  @_ignored_set = nil
  config.reset_notifiers!
end

.server_mode?Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/rails_informant.rb', line 139

def server_mode?
  defined?(Rails::Server)
end

.silenceObject



115
116
117
118
119
120
121
# File 'lib/rails_informant.rb', line 115

def silence
  was_silenced = Current.silenced
  Current.silenced = true
  yield
ensure
  Current.silenced = was_silenced
end