Handling Errors and Job Lifecycles in Rails 7.1: Master ActiveJob with `retry_on`, `discard_on`, and `after_discard`
Shah Zaib
Posted on November 5, 2024
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
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
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
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.
Let’s discuss how I can help you innovate and elevate your next project!
Posted on November 5, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.