Handling Errors and Job Lifecycles in Rails 7.1: Master ActiveJob with `retry_on`, `discard_on`, and `after_discard`

shahzaib

Shah Zaib

Posted on November 5, 2024

Handling Errors and Job Lifecycles in Rails 7.1: Master ActiveJob with `retry_on`, `discard_on`, and `after_discard`

Ruby on Rails 7.1 introduces some pivotal features to ActiveJob, streamlining error handling and job lifecycle management. In this post, I’ll walk you through how to effectively use after_discard, discard_on, and retry_on with examples to make your background job handling more robust.


1. after_discard Hook: Custom Actions for Discarded Jobs

Rails 7.1 introduces the after_discard callback, which lets you run custom logic when a job is discarded. It’s handy for logging errors, notifying administrators, or cleaning up resources.

Example:

class MyJob < ApplicationJob
  discard_on CustomError

  after_discard do |job|
    Rails.logger.info "Job #{job.job_id} was discarded."
    # You can add custom actions here, like sending notifications
  end

  def perform
    # Your job logic that might raise a CustomError
  end
end
Enter fullscreen mode Exit fullscreen mode

In this example, if CustomError occurs, the job gets discarded. The after_discard hook then logs the event and can trigger any additional custom behavior you need.


2. discard_on: Efficient Handling of Irrecoverable Errors

Use discard_on to specify exceptions that should result in discarding the job instead of retrying. This is crucial for errors you know cannot be fixed by retrying, like invalid data or a permanently missing record.

Example:

class ExampleJob < ApplicationJob
  discard_on ActiveRecord::RecordNotFound

  def perform(record_id)
    record = MyModel.find(record_id) # Raises an error if the record isn’t found
    # Perform your job logic on the record
  end
end
Enter fullscreen mode Exit fullscreen mode

When ActiveRecord::RecordNotFound is raised in this job, it is gracefully discarded without consuming additional resources or retries.


3. retry_on: Automatic Retries for Recoverable Errors

For errors that are likely temporary, retry_on provides a way to automatically retry jobs with configurable delays and limits. This is perfect for handling issues like network timeouts or transient service failures.

Example:

class RetryJob < ApplicationJob
  retry_on Net::OpenTimeout, wait: 5.seconds, attempts: 3

  def perform
    # Job logic that might encounter a temporary network issue
  end
end
Enter fullscreen mode Exit fullscreen mode

Here, if a Net::OpenTimeout error occurs, the job will retry up to three times with a 5-second pause between attempts, giving the external service a chance to recover.


Need a Rails Expert?

If you love what Rails can do and need a skilled full-stack developer to help you build robust, high-performance web applications, I'm available for new opportunities!

About Me: Shah Zaib

I’m a Full-Stack Developer and Technologist with 10+ years of experience delivering exceptional web projects. My expertise includes Ruby on Rails, Hotwire, and AI-powered solutions. From real-time app experiences to seamless AI integration, I’m passionate about transforming concepts into impactful software.

🌐 Connect with me on LinkedIn

Let’s discuss how I can help you innovate and elevate your next project!

💖 💪 🙅 🚩
shahzaib
Shah Zaib

Posted on November 5, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related