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") }
- D
- H
- N
- R
- S
- U
常量
DEFAULT_RESCUE | = | [StandardError].freeze |
DEFAULT_SOURCE | = | "application" |
SEVERITIES | = | %i(error warning info) |
UnexpectedError | = | Class.new(Exception) |
属性
[RW] | debug_mode | |
[RW] | logger |
类公共方法
new(*subscribers, logger: nil) 链接
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 35 def initialize(*subscribers, logger: nil) @subscribers = subscribers.flatten @logger = logger @debug_mode = false end
实例公共方法
disable(subscriber) 链接
阻止订阅者在代码块持续时间内收到错误通知。你可以传递订阅者本身或其类。
这在错误报告服务集成中可能很有用,当它们希望在堆栈中更高的地方处理任何错误时。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 185 def disable(subscriber) disabled_subscribers = (ActiveSupport::IsolatedExecutionState[self] ||= []) disabled_subscribers << subscriber begin yield ensure disabled_subscribers.delete(subscriber) end end
handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE) 链接
评估给定的代码块,报告并吞噬任何未处理的错误。如果未引发错误,则返回代码块的返回值。否则,返回fallback.call
的结果,如果未指定fallback
,则返回nil
。
# 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"
。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 78 def handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE) error_classes = DEFAULT_RESCUE if error_classes.empty? yield rescue *error_classes => error report(error, handled: true, severity: severity, context: context, source: source) fallback.call if fallback end
record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE) 链接
评估给定的代码块,报告并重新引发任何未处理的错误。如果未引发错误,则返回代码块的返回值。
# 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"
。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 114 def record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE) error_classes = DEFAULT_RESCUE if error_classes.empty? yield rescue *error_classes => error report(error, handled: false, severity: severity, context: context, source: source) raise end
report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE) 链接
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 210 def report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE) return if error.instance_variable_defined?(:@__rails_error_reported) ensure_backtrace(error) 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
set_context(...) 链接
更新错误订阅者可以访问的执行上下文。传递给 handle
、record
或 report
的任何上下文都将与在此设置的上下文合并。
Rails.error.set_context(section: "checkout", user_id: @user.id)
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 201 def set_context(...) ActiveSupport::ExecutionContext.set(...) end
subscribe(subscriber) 链接
注册新的错误订阅者。订阅者必须响应
report(Exception, handled: Boolean, severity: (:error OR :warning OR :info), context: Hash, source: String)
report
方法 **绝不** 应该引发错误。
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 161 def subscribe(subscriber) unless subscriber.respond_to?(:report) raise ArgumentError, "Error subscribers must respond to #report" end @subscribers << subscriber end
unexpected(error, severity: :warning, context: {}, source: DEFAULT_SOURCE) 链接
在生产环境中报告给定的错误,或者在开发或测试环境中引发它。
在生产环境中调用时,在报告错误后,此方法将返回 nil,并且执行将继续。
在开发环境中调用时,原始错误将包装在不同的错误类中,以确保它不被堆栈中更高的地方救援,并且将显示给开发人员。
此方法旨在用于报告关于先决条件的违反断言,或类似可以在生产环境中优雅处理但不应该发生的情况。
错误可以是异常实例或 String
。
example:
def edit
if published?
Rails.error.unexpected("[BUG] Attempting to edit a published article, that shouldn't be possible")
return false
end
# ...
end
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 145 def unexpected(error, severity: :warning, context: {}, source: DEFAULT_SOURCE) error = RuntimeError.new(error) if error.is_a?(String) if @debug_mode ensure_backtrace(error) raise UnexpectedError, "#{error.class.name}: #{error.message}", error.backtrace, cause: error else report(error, handled: true, severity: severity, context: context, source: source) end end
unsubscribe(subscriber) 链接
取消注册错误订阅者。接受订阅者或类。
subscriber = MyErrorSubscriber.new
Rails.error.subscribe(subscriber)
Rails.error.unsubscribe(subscriber)
# or
Rails.error.unsubscribe(MyErrorSubscriber)
来源:显示 | 在 GitHub 上
# File activesupport/lib/active_support/error_reporter.rb, line 176 def unsubscribe(subscriber) @subscribers.delete_if { |s| subscriber === s } end