Module: RailsInformant

Defined in:
lib/rails_informant.rb,
lib/rails_informant/event.rb,
lib/rails_informant/doctor.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/integration.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/claude_integration_content.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, ClaudeIntegrationContent, Mcp, Middleware, Notifiers Classes: ApplicationJob, ApplicationRecord, BreadcrumbBuffer, BreadcrumbSubscriber, Configuration, ContextBuilder, ContextFilter, Current, Doctor, Engine, ErrorGroup, ErrorRecorder, ErrorSubscriber, Event, Fingerprint, InstallGenerator, Integration, 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)


114
115
116
# File 'lib/rails_informant.rb', line 114

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

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



126
127
128
129
130
131
132
# File 'lib/rails_informant.rb', line 126

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)


68
69
70
71
# File 'lib/rails_informant.rb', line 68

def configure
  yield config
  reset_caches!
end

.console_mode?Boolean

Returns:

  • (Boolean)


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

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

.current_git_shaObject



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

def current_git_sha
  @_current_git_sha ||= resolve_git_sha
end

.ignored_exception?(exception) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rails_informant.rb', line 87

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)


102
103
104
105
106
107
108
# File 'lib/rails_informant.rb', line 102

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)


79
80
81
82
83
84
85
# File 'lib/rails_informant.rb', line 79

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



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

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

.reset_caches!Object



73
74
75
76
77
# File 'lib/rails_informant.rb', line 73

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

.server_mode?Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/rails_informant.rb', line 142

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

.silenceObject



118
119
120
121
122
123
124
# File 'lib/rails_informant.rb', line 118

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