Link to home
Start Free TrialLog in
Avatar of argon256
argon256

asked on

Handling exceptions raised in observers



I have a Rails (2.3.5) application where there are many groups, and each Group has_many People. I have a Group edit form where users can create new people. When a new person is created, they are sent an email (the email address is user entered on the form).

This is accomplished with an observer on the Person model. The problem comes when ActionMailer throws an exception - for example if the domain does not exist. Clearly that cannot be weeded out with a validation.

There would seem to be 2 ways to deal with this:

   1. A begin...rescue...end block in the observer around the mailer.
      The problem with this is that the only way to pass any feedback to the user would be to set a global variable - as the observer is out of the MVC flow, I can't even set a flash[:error] there.
   2. A rescue_from in the Groups controller.
      This works fine, but has 2 problems. Firstly, there is no way to know which person threw the exception (all I can get is the 503 exception, no way to know which person caused the problem). This would be useful information to be able to pass back to the user - at the moment, there is no way for me to let them know which email address is the problem - at the moment, I just have to chuck the lot back at them, and issue an unhelpful message saying that one of them is not correct. Secondly (and to a certain extent this make the first point moot) it seems that it is necessary to call a render in the rescue_from, or it dies with a rather bizarre "can't convert Array into String" error from webbrick, with no stack trace & nothing in the log. Thus, I have to throw it back to the user when I come across the first error and have to stop processing the rest of the emails.

Neither of the solutions are optimal. It would seem that the only way to get Rails to do what I want is option 1, and loathsome global variables. This would also rely on Rails being single threaded.

Can anyone suggest a better solution to this problem?
Avatar of wesgarrison
wesgarrison
Flag of United States of America image

Some ideas:

Don't use an observer.  Loop through each new person, call deliver_... for them, catch any exceptions.

Send your email through a service like http://postmarkapp.com/ and then manage the bounces/exceptions through that.

Also, install mongrel or thin for local development instead of webrick to see if that fixes your Array to String error.
Avatar of argon256
argon256

ASKER

I had wondered about getting rid of the observer, but it means dealing with Person specific code within the Group controller, which isn't really where it belongs.  Maybe less dirty than the alternatives.
Make a method in Person and call it from the Group looping over new persons.
Or, use an before/after_create callback in Person to keep it all in Person.
ASKER CERTIFIED SOLUTION
Avatar of argon256
argon256

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Southmod

The post of cs97jjm3 implied that how this question was closed was now up to the moderators, not me.  I had left the question open in the hope that a passing Rubyist might provide further assistance.  If that's not acceptable then fine, I'll close the question with no points awarded.

In light of the cs97jjm3's post, your first paragraph is unnecessary, patronising and inflammatory.  There are plenty of other internet help fora, and if you want to keep people coming to this one, try not flaming those asking for help.  The same advice could have been delivered with politeness.