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