How to send Airbrake errors from ActiveJob

--

Most of the work our new online privacy tool Marshal does is behind the scenes, running as processes managed by ActiveJob backed by Rescue. On rare occasion, something goes wrong in those jobs and an exception is thrown. Despite catching and handling those errors, we found they were not making it to Airbrake. Here’s how we fixed it.

Though we were certain (through logging statements) that Airbrake.notify was being called, none of those messages were making it to Airbrake. It worked as expected in the console, and even in Resque Scheduler, so why weren’t they sent from jobs enqueued by ActiveJob and executed by Resque Pool?

Googling “ActiveJob not notifying Airbrake” (followed by an increasingly complex sequence of variations) never magically answered my question with a snippet from Stack Overflow. Even Airbrake’s documentation doesn’t acknowledge that something with ActiveJob and Airbrake doesn’t always play nice together. What gives?

After poking around the Airbrake documentation and code, we finally got those notifications sending with a simple change. In our background processes, we switched our calls to Airbrake.notify to beAirbrake.notify_sync instead. The arguments are the same, so just replace the method name.

Airbrake.notify_sync sends the message synchronously, which is just dandy for background jobs, while not desirable in the request-response cycle. It appears that the Future returned by Airbrake.notify never gets a chance to execute, probably because Resque Pool is killing the process as soon as the job is done.

As you’re building error handling into your application, remember to use Airbrake.notify_sync in those places that are already running outside the request response cycle.

--

--