# frozen-string-literal: true require 'net/smtp' class Roda module RodaPlugins # The error_email plugin adds an +error_email+ instance method that # send an email related to the exception. This is most useful if you are # also using the error_handler plugin: # # plugin :error_email, to: 'to@example.com', from: 'from@example.com' # plugin :error_handler do |e| # error_email(e) # 'Internal Server Error' # end # # It is similar to the error_mail plugin, except that it uses net/smtp # directly instead of using the mail library. If you are not already using the # mail library in your application, it makes sense to use error_email # instead of error_mail. # # Options: # # :filter :: Callable called with the key and value for each parameter, environment # variable, and session value. If it returns true, the value of the # parameter is filtered in the email. # :from :: The From address to use in the email (required) # :headers :: A hash of additional headers to use in the email (default: empty hash) # :host :: The SMTP server to use to send the email (default: localhost) # :prefix :: A prefix to use in the email's subject line (default: no prefix) # :to :: The To address to use in the email (required) # # The subject of the error email shows the exception class and message. # The body of the error email shows the backtrace of the error and the # request environment, as well the request params and session variables (if any). # You can also call error_email with a plain string instead of an exception, # in which case the string is used as the subject, and no backtrace is included. # # Note that emailing on every error as shown above is only appropriate # for low traffic web applications. For high traffic web applications, # use an error reporting service instead of this plugin. module ErrorEmail DEFAULTS = { :filter=>lambda{|k,v| false}, :headers=>OPTS, :host=>'localhost', # :nocov: :emailer=>lambda{|h| Net::SMTP.start(h[:host]){|s| s.send_message(h[:message], h[:from], h[:to])}}, # :nocov: :default_headers=>lambda do |h, e| subject = if e.respond_to?(:message) "#{e.class}: #{e.message}" else e.to_s end {'From'=>h[:from], 'To'=>h[:to], 'Subject'=>"#{h[:prefix]}#{subject}"} end, :body=>lambda do |s, e| filter = s.opts[:error_email][:filter] format = lambda do |h| h = h.map{|k, v| "#{k.inspect} => #{filter.call(k, v) ? 'FILTERED' : v.inspect}"} h.sort! h.join("\n") end begin params = s.request.params params = (format[params] unless params.empty?) rescue params = 'Invalid Parameters!' end message = String.new message << <