evendis / mandrill-rails

Webhook processing and event decoration to make using Mandrill with Rails just that much easier
MIT License
288 stars 36 forks source link

Mandrill::WebHook::EventDecorator class extension not getting loaded #22

Closed betjaminrichards closed 9 years ago

betjaminrichards commented 9 years ago

Hi,

I've extended the Mandrill::WebHook::EventDecorator class as described in the documentation by creating a new decorator in decorators > mandrill > webhook > event_decorator.rb in my app.

class Mandrill::WebHook::EventDecorator

  def bounce_details
    [bounce_description, bounce_diagnosis].reject(&:blank?).join('. ')
  end

  def bounce_description
    self['msg']['bounce_description'] if self['msg'] && self['msg']['bounce_description']
  end

  def bounce_diagnosis
    self['msg']['diag'] if self['msg'] && self['msg']['diag']
  end
end

My app receives requests for Mandrill fine and then starts a Delayed::Job method which process the payload.

However, when this delayed job is run I get an error:

Job Class#delayed_create_without_delay (id=2048) FAILED (0 prior attempts) with NoMethodError: undefined method `bounce_details' for #<Mandrill::WebHook::EventDecorator:0x007f64b642f988>

It seems like the my class extension is getting loaded properly. Any ideas?

tardate commented 9 years ago

Hi @betjaminrichards

Most of the time, this kind of issue with delayed_job is because the delayed job process has not been restarted with the new codebase. Have you stopped/restarted DelayedJob?

If you have a trickier delayed job deployment (outside the rails codebase, or you have selectively required the extensions), it may be that delayed job isn't seeing the new code at all. Check your requires etc.

betjaminrichards commented 9 years ago

Thanks @tardate

I've restarted delayed job with the new code base and I'm not selectively loading extensions.

I wonder whether I have the file in the correct place? (decorators > mandrill > webhook > event_decorator.rb) should it be in the initializers folder instead?

tardate commented 9 years ago

@betjaminrichards ahah, in that case, I'm presuming the place you have the code is not getting loaded/autoloaded. Yes, putting it in initializers would fix it, but that's kind of brute force. If you have any config.autoload_paths it could be there e.g. lib. Else you'll need to require the file with your extension code from some file that is getting loaded.

One way to test if you have a general issue getting the file loaded is if you startup the console and try:

Mandrill::WebHook::EventDecorator[{}].bounce_details

If you get NoMethodError on bounce_details then you code has not been found/loaded.

betjaminrichards commented 9 years ago

Strange. @tardate when I run the console Mandrill::WebHook::EventDecorator[{}].bounce_details I'm getting no error, it's just return a blank string (what I would expect).

irb(main):001:0> Mandrill::WebHook::EventDecorator[{}].bounce_details
=> ""

Which means it's getting loaded properly when in the console.

I have the following in my application.rb file: config.autoload_paths += %W(#{config.root}/app) and the new class file in app > decorators > mandrill > webhook > event_decorator.rb and it's obviously loading it in the console, so it must have something to do with Delayed::Job and how it loads classes.

tardate commented 9 years ago

@betjaminrichards I'm out of suggestions, sorry;-(

I actually run just like this on one site - custom EventDecorator, incoming event task thrown on a delayed job queue. The only difference is it is not relying on autoload_paths .. we have explicit require statements for various extensions.

But AFAIK, if the console picks up the class, then DelayedJob worker should too. I'd be double-checking I don't have an old/orphaned DJ worker running somewhere that is confusing the picture

Perhaps you could try putting an explicit require to your file in an initialiser?

betjaminrichards commented 9 years ago

@tardate

I've fixed it. What I did was add the following to a new file config/initializers/mandrill_custom_decorator.rb

require 'decorators/mandrill/webhook/event_decorator.rb'

This loads the custom decorator class for Delayed::Job and now I get no more NoMethodErrors.

You may want to add this to the readme for others who run into a similar problem.

tardate commented 9 years ago

@betjaminrichards tardy reply I know ... but that's good news! I'll close of the issue..