class ActiveSupport::ErrorReporter
Отчётчик об ошибках Active Support
ActiveSupport::ErrorReporter — это общий интерфейс для служб отчёта об ошибках.
Чтобы перехватить и отправить любой необработанный вызов ошибки, можно использовать метод handle:
Rails.error.handle do do_something! end
Если произойдёт ошибка, она будет обработана и проигнорирована.
В качестве альтернативы, если вы хотите отправить ошибку, но не проигнорировать её, используйте record:
Rails.error.record do do_something! end
Оба метода можно ограничить обработкой только определённого класса ошибок:
maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
Константы
- DEFAULT_SOURCE
- SEVERITIES
Атрибуты
Публичные методы класса
# File activesupport/lib/active_support/error_reporter.rb, line 32 def initialize(*subscribers, logger: nil) @subscribers = subscribers.flatten @logger = logger end
Публичные методы экземпляра
# File activesupport/lib/active_support/error_reporter.rb, line 147
def disable(subscriber)
disabled_subscribers = (ActiveSupport::IsolatedExecutionState[self] ||= [])
disabled_subscribers << subscriber
begin
yield
ensure
disabled_subscribers.delete(subscriber)
end
end Запретить уведомление подписчика об ошибках на время выполнения блока. Можно передать самого подписчика или его класс.
Это может быть полезно для интеграций с сервисами отчёта об ошибках, когда они хотят обработать ошибки в более высоких уровнях стека.
# File activesupport/lib/active_support/error_reporter.rb, line 74
def handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE)
error_classes = [StandardError] if error_classes.blank?
yield
rescue *error_classes => error
report(error, handled: true, severity: severity, context: context, source: source)
fallback.call if fallback
end Выполняет указанный блок, сообщая об ошибках и игнорируя их. Если ошибка не возникла, возвращает результат выполнения блока. В противном случае возвращает результат fallback.call, или nil, если fallback не указан.
# Will report a TypeError to all subscribers and return nil. Rails.error.handle do 1 + '1' end
Можно ограничить обработку только определёнными классами ошибок:
maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
Параметры
-
:severity— Это значение передаётся подписчикам, чтобы указать, насколько важен отчёт об ошибке. Может быть:error,:warning, или:info. По умолчанию:warning. -
:context— Дополнительная информация, передаваемая подписчикам. Например:Rails.error.handle(context: { section: "admin" }) do # ... end -
:fallback— Функция, которая предоставляет значение возвратаhandleпри возникновении необработанной ошибки. Например:user = Rails.error.handle(fallback: -> { User.anonymous }) do User.find_by(params) end -
:source— Это значение передаётся подписчикам, чтобы указать источник ошибки. Подписчики могут использовать это значение для игнорирования определённых ошибок. По умолчанию"application".
# File activesupport/lib/active_support/error_reporter.rb, line 110
def record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE)
error_classes = [StandardError] if error_classes.blank?
yield
rescue *error_classes => error
report(error, handled: false, severity: severity, context: context, source: source)
raise
end Выполняет указанный блок, сообщая об ошибках и повторно поднимая их. Если ошибка не возникла, возвращает результат выполнения блока.
# Will report a TypeError to all subscribers and re-raise it. Rails.error.record do 1 + '1' end
Можно ограничить обработку только определёнными классами ошибок:
tags = Rails.error.record(Redis::BaseError) { redis.get("tags") }
Параметры
-
:severity— Это значение передаётся подписчикам, чтобы указать, насколько важен отчёт об ошибке. Может быть:error,:warning, или:info. По умолчанию:error. -
:context— Дополнительная информация, передаваемая подписчикам. Например:Rails.error.record(context: { section: "admin" }) do # ... end -
:source— Это значение передаётся подписчикам, чтобы указать источник ошибки. Подписчики могут использовать это значение для игнорирования определённых ошибок. По умолчанию"application".
# File activesupport/lib/active_support/error_reporter.rb, line 172
def report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE)
return if error.instance_variable_defined?(:@__rails_error_reported)
unless SEVERITIES.include?(severity)
raise ArgumentError, "severity must be one of #{SEVERITIES.map(&:inspect).join(", ")}, got: #{severity.inspect}"
end
full_context = ActiveSupport::ExecutionContext.to_h.merge(context)
disabled_subscribers = ActiveSupport::IsolatedExecutionState[self]
@subscribers.each do |subscriber|
unless disabled_subscribers&.any? { |s| s === subscriber }
subscriber.report(error, handled: handled, severity: severity, context: full_context, source: source)
end
rescue => subscriber_error
if logger
logger.fatal(
"Error subscriber raised an error: #{subscriber_error.message} (#{subscriber_error.class})\n" +
subscriber_error.backtrace.join("\n")
)
else
raise
end
end
unless error.frozen?
error.instance_variable_set(:@__rails_error_reported, true)
end
nil
end Отправить ошибку напрямую подписчикам. Этот метод можно использовать, когда методы блочного типа handle и record не подходят.
Rails.error.report(error)
# File activesupport/lib/active_support/error_reporter.rb, line 163 def set_context(...) ActiveSupport::ExecutionContext.set(...) end
Обновить контекст выполнения, доступный подписчикам ошибок. Любой контекст, переданный в handle, record или report, будет объединён с контекстом, установленным здесь.
Rails.error.set_context(section: "checkout", user_id: @user.id)
# File activesupport/lib/active_support/error_reporter.rb, line 123
def subscribe(subscriber)
unless subscriber.respond_to?(:report)
raise ArgumentError, "Error subscribers must respond to #report"
end
@subscribers << subscriber
end Регистрация нового подписчика ошибок. Подписчик должен отвечать на
report(Exception, handled: Boolean, severity: (:error OR :warning OR :info), context: Hash, source: String)
Метод report никогда не должен генерировать ошибку.
# File activesupport/lib/active_support/error_reporter.rb, line 138
def unsubscribe(subscriber)
@subscribers.delete_if { |s| subscriber === s }
end Отписаться от подписчика ошибок. Принимает либо самого подписчика, либо его класс.
subscriber = MyErrorSubscriber.new Rails.error.subscribe(subscriber) Rails.error.unsubscribe(subscriber) # or Rails.error.unsubscribe(MyErrorSubscriber)
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.