Index: app/controllers/users_controller.rb =================================================================== --- app/controllers/users_controller.rb (revision 2940) +++ app/controllers/users_controller.rb (working copy) @@ -39,12 +39,16 @@ begin UserMailer.deliver_signup(@user, request.host_with_port, params[:to]) rescue Net::SMTPFatalError => e + smtp_error(e) flash[:notice] = "A permanent error occured while sending the signup message to '{email}'. Please check the e-mail address."[:signup_permanent_error_message, @user.email] redirect_to :action => "new" + return rescue Net::SMTPServerBusy, Net::SMTPUnknownError, \ Net::SMTPSyntaxError, TimeoutError => e + smtp_error(e) flash[:notice] = "The signup message cannot be sent to '{email}' at this moment. Please, try again later."[:signup_cannot_sent_message, @user.email] redirect_to :action => "new" + return end flash[:notice] = params[:email] ? "A temporary login email has been sent to '{email}'."[:temporary_login_message, @user.email] : "An account activation email has been sent to '{email}'."[:account_activation_message, @user.email] redirect_to CGI.unescape(login_path) @@ -103,4 +107,8 @@ def find_user @user = params[:id] ? User.find_by_id(params[:id]) : current_user end + + def smtp_error(error) + logger.error("Error sending email to #{@user.email}: #{error.class.name} '#{error}'\n#{error.backtrace*"\n"}") + end end Index: test/functional/users_controller_test.rb =================================================================== --- test/functional/users_controller_test.rb (revision 2940) +++ test/functional/users_controller_test.rb (working copy) @@ -15,7 +15,28 @@ @controller = UsersController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new + + UserMailer.class_eval do + unless method_defined? :signup_response + def signup_with_failure(user, domain, redirect_path, sent_at = Time.now) + case signup_response + when :fatal + raise Net::SMTPFatalError.new('error!') + when :server_busy + raise Net::SMTPServerBusy.new('error!') + else + signup_without_failure(user, domain, redirect_path, sent_at) + end + end + alias_method_chain :signup, :failure + cattr_accessor :signup_response + end + end end + + def teardown + UserMailer.signup_response = :default + end def test_should_get_index get :index @@ -261,4 +282,16 @@ assert users(:sam).reload.activated? assert_redirected_to home_path end + + def test_should_not_bomb_on_permanent_smtp_errors + UserMailer.signup_response = :fatal + post :create, :user => { :login => 'nico', :email => 'nico@email.com', :password => 'fooey', :password_confirmation => 'fooey' } + assert_redirected_to :controller => 'users', :action => 'new' + end + + def test_should_not_bomb_on_temporary_smtp_errors + UserMailer.signup_response = :server_busy + post :create, :user => { :login => 'nico', :email => 'nico@email.com', :password => 'fooey', :password_confirmation => 'fooey' } + assert_redirected_to :controller => 'users', :action => 'new' + end end Index: test/fixtures/users.yml =================================================================== --- test/fixtures/users.yml (revision 2940) +++ test/fixtures/users.yml (working copy) @@ -22,7 +22,7 @@ last_seen_at: <%= 4.minutes.ago.to_s :db %> activated: true login_key: 8305f94ab2b92f99137abbc235ee28e5a - login_key_expires_at: <%= Time.now.utc + 1.week %> + login_key_expires_at: <%= (Time.now.utc + 1.week).to_s :db %> joe: id: 3 login: joe