Search code examples
ruby-on-rails-5rails-activejobrescue

Rails5, ActiveJob rescue_from not working


I am trying to reproduce this example code: https://apidock.com/rails/ActiveJob/Enqueuing/retry_job but I don't manage to make the rescue_from working in an ActiveJob

Steps to reproduce

I have prepared a test project:

Expected behavior

In this Job:

I am expecting to see the rescue_from message when I perform the Job:

irb(main):005:0> TestJobJob.perform_now

Actual behavior

Instead of the message I see the Exception been propagated:

irb(main):004:0> TestJobJob.perform_now
Performing TestJobJob from Async(default)
Performed TestJobJob from Async(default) in 0.82ms
Exception: This is the error message
    from /Users/fguillen/Development/Temp/TestingActiveJobRescueFrom/app/jobs/test_job_job.rb:9:in `perform'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activejob-5.0.2/lib/active_job/execution.rb:34:in `block in perform_now'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/callbacks.rb:126:in `call'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/callbacks.rb:506:in `block (2 levels) in compile'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/callbacks.rb:455:in `call'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/callbacks.rb:448:in `block (2 levels) in around'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/callbacks.rb:286:in `block (2 levels) in halting'
    from /Users/fguillen/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/i18n-0.8.1/lib/i18n.rb:257:in `with_locale'

Same behaviour when I try to reproduce the issue in a test:

System configuration

Rails version: 5.0.2 Ruby version: 2.3.1p112


Solution

  • As opposed of the ActionController::Base.rescue_from behaviour which actually captures any Exception:

    class MyTestsController < ApplicationController
      rescue_from Exception do |exception|
        render plain: "Rescuing the exception: '#{exception}'", status: 500
      end
    
      def raise_exception
        raise Exception.new("This is an Exception")
      end
    
      def raise_standard_error
        raise StandardError.new("This is an StandardError")
      end
    end
    

    Example code

    ActiveJob::Base.rescue_from only captures classes inheriting from StandardError:

    class TestJob2Job < ApplicationJob
      rescue_from Exception do |exception|
        Rails.logger.info "I am on rescue_from: #{exception}"
      end
    
      def perform(*args)
        raise StandardError.new("This is the error message")
      end
    end
    

    Example code

    You can see the conversation with the maintainers here: https://github.com/rails/rails/issues/28874#issuecomment-297599254