1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00

Use exception handler for logging for fetch exception

Extends the `ExceptionHandler` to support multiple log levels and
additional context text in order to use it when the `Processor`
encounters an exception when fetching new work. The added options ensure
that the new behavior is fairly close to the old behavior (same log
level, same fetch error message).

Fixes 
This commit is contained in:
Rachael Ludwick 2017-11-22 13:42:39 -08:00 committed by Mike Perham
parent ae6f4aa7fc
commit 58d5ff1e6d
3 changed files with 28 additions and 12 deletions

View file

@ -5,20 +5,26 @@ module Sidekiq
module ExceptionHandler
class Logger
def call(ex, ctxHash)
Sidekiq.logger.warn(Sidekiq.dump_json(ctxHash)) if !ctxHash.empty?
Sidekiq.logger.warn "#{ex.class.name}: #{ex.message}"
Sidekiq.logger.warn ex.backtrace.join("\n") unless ex.backtrace.nil?
def call(ex, ctxHash, options={})
# In practice, this will only be called on exceptions so this increase
# in complexity in selecting log level is low compared to expense of
# the logging messages themselves.
options = options || {}
level = options.fetch(:level, :warn)
Sidekiq.logger.send(level, options[:message]) if options.key?(:message)
Sidekiq.logger.send(level, Sidekiq.dump_json(ctxHash)) if !ctxHash.empty?
Sidekiq.logger.send(level, "#{ex.class.name}: #{ex.message}")
Sidekiq.logger.send(level, ex.backtrace.join("\n")) unless ex.backtrace.nil?
end
# Set up default handler which just logs the error
Sidekiq.error_handlers << Sidekiq::ExceptionHandler::Logger.new
end
def handle_exception(ex, ctxHash={})
def handle_exception(ex, ctxHash={}, options={})
Sidekiq.error_handlers.each do |handler|
begin
handler.call(ex, ctxHash)
handler.call(ex, ctxHash, options)
rescue => ex
Sidekiq.logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
Sidekiq.logger.error ex

View file

@ -110,10 +110,7 @@ module Sidekiq
def handle_fetch_exception(ex)
if !@down
@down = Time.now
logger.error("Error fetching job: #{ex}")
ex.backtrace.each do |bt|
logger.error(bt)
end
handle_exception(ex, {}, level: :error, message: 'Error fetching job:')
end
sleep(1)
nil

View file

@ -69,8 +69,8 @@ class TestProcessor < Sidekiq::Test
describe 'exception handling' do
let(:errors) { [] }
let(:error_handler) do
proc do |exception, context|
errors << { exception: exception, context: context }
proc do |exception, context, options={}|
errors << { exception: exception, context: context, options: options }
end
end
@ -128,6 +128,19 @@ class TestProcessor < Sidekiq::Test
assert_equal msg, errors.first[:context][:jobstr]
assert_equal job_hash, errors.first[:context][:job]
end
it 'handles exceptions raised during fetch' do
fetch_stub = lambda { raise StandardError, "fetch exception" }
# swallow logging because actually care about the added exception handler
capture_logging do
@processor.instance_variable_get('@strategy').stub(:retrieve_work, fetch_stub) do
@processor.process_one
end
end
assert_instance_of StandardError, errors.last[:exception]
assert_equal :error, errors.last[:options][:level]
end
end
describe 'acknowledgement' do