2012-01-03 40 views
17

Vấn đề là làm thế nào tôi có thể bắt ngoại lệ trong việc gửi thư bằng ActionMailer. Đối với tôi nó có vẻ không thể, bởi vì trong trường hợp này ActionMailer nên gửi mail đến mailserver, và nếu mailserver trả về lỗi, ActionMailer sẽ cho tôi thấy lỗi này. Tôi chỉ quan tâm đến việc đếm thư chưa được gửi.Cách bắt ngoại lệ lỗi trong ActionMailer

Bạn có ý tưởng nào về cách triển khai tính năng này không? Cảm ơn!

Trả lời

23

Tôi đang sử dụng một cái gì đó như thế này trong bộ điều khiển:

if @user.save 
     begin 
     UserMailer.welcome_email(@user).deliver 
     flash[:success] = "#{@user.name} created" 
     rescue Net::SMTPAuthenticationError, Net::SMTPServerBusy, Net::SMTPSyntaxError, Net::SMTPFatalError, Net::SMTPUnknownError => e 
     flash[:success] = "Utente #{@user.name} creato. Problems sending mail" 
     end 
     redirect_to "/" 
11

Điều này sẽ hoạt động trong bất kỳ tệp môi trường nào của bạn. development.rb hoặc production.rb

config.action_mailer.raise_delivery_errors = true 
+0

Tôi không muốn để hiển thị các ngoại lệ đối với người sử dụng, tôi chỉ cần xác định rằng giao hàng thất bại – com

+2

Người dùng sẽ không thấy ngoại lệ miễn là bạn giải cứu và xử lý nó! Tôi cũng muốn báo cáo mọi thứ với Airbrake hoặc một số dịch vụ thông báo ngoại lệ để chúng tôi biết nếu mọi thứ không thành công — ngay cả khi chúng được xử lý một cách vui vẻ. – Ricky

5

Nếu bạn đang gửi rất nhiều email, bạn cũng có thể giữ mã của bạn khô hơn và nhận được thông báo về trường hợp ngoại lệ đến email của bạn bằng cách làm một cái gì đó như thế này:

status = Utility.try_delivering_email do 
    ClientMailer.signup_confirmation(@client).deliver 
end 

unless status 
    flash.now[:error] = "Something went wrong when we tried sending you and email :(" 
end 

Utility class:

class Utility 
    # Logs and emails exception 
    # Optional args: 
    # request: request Used for the ExceptionNotifier 
    # info: "A descriptive messsage" 
    def self.log_exception(e, args = {}) 
    extra_info = args[:info] 

    Rails.logger.error extra_info if extra_info 
    Rails.logger.error e.message 
    st = e.backtrace.join("\n") 
    Rails.logger.error st 

    extra_info ||= "<NO DETAILS>" 
    request = args[:request] 
    env = request ? request.env : {} 
    ExceptionNotifier::Notifier.exception_notification(env, e, :data => {:message => "Exception: #{extra_info}"}).deliver 
    end 

    def self.try_delivering_email(options = {}, &block) 
    begin 
     yield 
     return true 
    rescue EOFError, 
      IOError, 
      TimeoutError, 
      Errno::ECONNRESET, 
      Errno::ECONNABORTED, 
      Errno::EPIPE, 
      Errno::ETIMEDOUT, 
      Net::SMTPAuthenticationError, 
      Net::SMTPServerBusy, 
      Net::SMTPSyntaxError, 
      Net::SMTPUnknownError, 
      OpenSSL::SSL::SSLError => e 
     log_exception(e, options) 
     return false 
    end 
    end 
end 

Got cảm hứng ban đầu của tôi từ đây: http://www.railsonmaui.com/blog/2013/05/08/strategies-for-rails-logging-and-error-handling/

+0

Nó không cần phải là một lớp học. Chỉ cần một mô-đun và bạn có thể xác định các phương thức với 'module_function' –

Các vấn đề liên quan