views:

546

answers:

3

I have been happily using the DelayedJob idiom:

foo.send_later(:bar)

This calls the method bar on the object foo in the DelayedJob process.

And I've been using DaemonSpawn to kick off the DelayedJob process on my server.

But... if foo throws an exception Hoptoad doesn't catch it.

Is this a bug in any of these packages... or do I need to change some configuration... or do I need to insert some exception handling in DS or DJ that will call the Hoptoad notifier?


In response to the first comment below.

class DelayedJobWorker < DaemonSpawn::Base
def start(args)
  ENV['RAILS_ENV'] ||= args.first || 'development'
  Dir.chdir RAILS_ROOT
  require File.join('config', 'environment')

  Delayed::Worker.new.start
end
A: 

Just throwing it out there - your daemon should require the rails environment that you're working on. It should look something along the lines of:

RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'production'
require File.join('config', 'environment')

This way you can specify environment in which daemon is called.

Since it runs delayed job chances are daemon already does that (it needs activerecord), but maybe you're only requiring minimal activerecord to make delayed_job happy without rails.

hakunin
That's a good answer, but DJ does do that when it starts. DJ starts from script/delayed_job and contains this code:class DelayedJobWorker < DaemonSpawn::Base def start(args) ENV['RAILS_ENV'] ||= args.first || 'development' Dir.chdir RAILS_ROOT require File.join('config', 'environment') Delayed::Worker.new.start end...etc...So yes the full environment is loaded, I just don't know why the Hoptoad notification code isn't automagically plugging itself in here.
john Merrells
+1  A: 

Hoptoad uses the Rails rescue_action_in_public hook method to intercept exceptions and log them. This method is only executed when the request is dispatched by a Rails controller. For this reason, Hoptoad is completely unaware of any exception generated, for example, by rake tasks or the rails script/runner.

If you want to have Hoptoad tracking your exception, you should manually integrate it. It should be quite straightforward. The following code fragment demonstrates how Hoptoad is invoked

def rescue_action_in_public_with_hoptoad exception
  notify_hoptoad(exception) unless ignore?(exception) || ignore_user_agent?
  rescue_action_in_public_without_hoptoad(exception)
end

Just include Hoptoad library in your environment and call notify_hoptoad(exception) should work. Make sure your environment provides the same API of a Rails controller or Hoptoad might complain.

Simone Carletti
+2  A: 

Check out the source for Delayed::Job... there's a snippet like:

# This is a good hook if you need to report job processing errors in additional or different ways
def log_exception(error)
  logger.error "* [JOB] #{name} failed with #{error.class.name}: #{error.message} - #{attempts} failed attempts"
  logger.error(error)
end

I haven't tried it, but I think you could do something like:

class Delayed::Job
  def log_exception_with_hoptoad(error)
    log_exception_without_hoptoad(error)
    HoptoadNotifier.notify(error)
  end

  alias_method_chain :log_exception, :hoptoad
end
technicalpickles