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?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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.
argon256Author Commented:
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.
argon256Author Commented:
I'm not sure that either answer really helps, and I ended up going with method 2 in my original question, and forsaking the functionality that I was looking for.  There are other methods of creating a person, so this is exactly the circumstances in which an observer ought to be used.  That said it may be that using an after_create may work, but I am pretty sure that the same problem of passing the information back to the groups controller will arise - I do not think that this will be possible without using a global variable, so I haven't tried implementing this.

I don't think that either of the replies therefore quite meet the criteria of the question, but clearly deserve points for effort - would a half award to wesgarrison be appropriate?

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
argon256Author Commented:

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.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.