Merge pull request #4984 from LeoMcA/unrecognized-error-email

FEATURE: send rejection email for unrecognized errors
This commit is contained in:
Régis Hanol 2017-07-21 20:40:18 +02:00 committed by GitHub
commit fff5e2c3a5
4 changed files with 83 additions and 7 deletions

View File

@ -15,6 +15,7 @@ class Admin::EmailTemplatesController < Admin::AdminController
"system_messages.email_reject_reply_key", "system_messages.email_reject_topic_closed",
"system_messages.email_reject_topic_not_found",
"system_messages.email_reject_screened_email",
"system_messages.email_reject_unrecognized_error",
"system_messages.pending_users_reminder", "system_messages.post_hidden",
"system_messages.restore_failed", "system_messages.restore_succeeded",
"system_messages.spam_post_blocked", "system_messages.too_many_spam_flags",

View File

@ -2269,6 +2269,14 @@ en:
Your email was marked as "auto generated", which means it was automatically created by a computer instead of being typed by a human; we can't accept those kinds of emails. If you believe this is an error, contact a staff member.
email_reject_unrecognized_error:
title: "Email Reject Unrecognized Error"
subject_template: "[%{email_prefix}] Email issue -- Unrecognized Error"
text_body_template: |
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
There was an unrecognized error while processing your email and it wasn't posted. You should try again, or contact a staff member.
email_error_notification:
title: "Email Error Notification"
subject_template: "[%{email_prefix}] Email issue -- POP authentication error"

View File

@ -52,6 +52,7 @@ module Email
when ActiveRecord::Rollback then :email_reject_invalid_post
when Email::Receiver::InvalidPostAction then :email_reject_invalid_post_action
when Discourse::InvalidAccess then :email_reject_invalid_access
else :email_reject_unrecognized_error
end
template_args = {}
@ -63,6 +64,14 @@ module Email
template_args[:post_error] = e.message
end
if message_template == :email_reject_unrecognized_error
msg = "Unrecognized error type (#{e.class}: #{e.message}) when processing incoming email"
msg += "\n\nBacktrace:\n#{e.backtrace.map { |l| " #{l}" }.join("\n")}"
msg += "\n\nMail:\n#{mail_string}"
Rails.logger.error(msg)
end
if message_template
# inform the user about the rejection
message = Mail::Message.new(mail_string)
@ -76,18 +85,14 @@ module Email
if can_send_rejection_email?(message.from, message_template)
Email::Sender.new(client_message, message_template).send
end
else
msg = "Unrecognized error type (#{e.class}: #{e.message}) when processing incoming email"
msg += "\n\nBacktrace:\n#{e.backtrace.map { |l| " #{l}" }.join("\n")}"
msg += "\n\nMail:\n#{mail_string}"
Rails.logger.error(msg)
end
client_message
end
def can_send_rejection_email?(email, type)
return true if type == :email_reject_unrecognized_error
key = "rejection_email:#{email}:#{type}:#{Date.today}"
if $redis.setnx(key, "1")

View File

@ -3,9 +3,11 @@ require "email/processor"
describe Email::Processor do
let(:from) { "foo@bar.com" }
describe "rate limits" do
let(:mail) { "From: foo@bar.com\nTo: bar@foo.com\nSubject: FOO BAR\n\nFoo foo bar bar?" }
let(:mail) { "From: #{from}\nTo: bar@foo.com\nSubject: FOO BAR\n\nFoo foo bar bar?" }
let(:limit_exceeded) { RateLimiter::LimitExceeded.new(10) }
before do
@ -24,4 +26,64 @@ describe Email::Processor do
end
context "known error" do
let(:mail) { "From: #{from}\nTo: bar@foo.com" }
let(:mail2) { "From: #{from}\nTo: foo@foo.com" }
let(:mail3) { "From: #{from}\nTo: foobar@foo.com" }
it "only sends one rejection email per day" do
key = "rejection_email:#{[from]}:email_reject_empty:#{Date.today}"
$redis.expire(key, 0)
expect {
Email::Processor.process!(mail)
}.to change { EmailLog.count }.by(1)
expect {
Email::Processor.process!(mail2)
}.to change { EmailLog.count }.by(0)
Timecop.freeze(Date.today + 1)
key = "rejection_email:#{[from]}:email_reject_empty:#{Date.today}"
$redis.expire(key, 0)
expect {
Email::Processor.process!(mail3)
}.to change { EmailLog.count }.by(1)
end
end
context "unrecognized error" do
let(:mail) { "From: #{from}\nTo: bar@foo.com\nSubject: FOO BAR\n\nFoo foo bar bar?" }
let(:mail2) { "From: #{from}\nTo: foo@foo.com\nSubject: BAR BAR\n\nBar bar bar bar?" }
it "sends a rejection email on an unrecognized error" do
Email::Processor.any_instance.stubs(:can_send_rejection_email?).returns(true)
Email::Receiver.any_instance.stubs(:process_internal).raises("boom")
Rails.logger.expects(:error)
Email::Processor.process!(mail)
expect(IncomingEmail.first.error).to eq("boom")
expect(IncomingEmail.first.rejection_message).to be_present
expect(EmailLog.first.email_type).to eq("email_reject_unrecognized_error")
end
it "sends more than one rejection email per day" do
Email::Receiver.any_instance.stubs(:process_internal).raises("boom")
key = "rejection_email:#{[from]}:email_reject_unrecognized_error:#{Date.today}"
$redis.expire(key, 0)
expect {
Email::Processor.process!(mail)
}.to change { EmailLog.count }.by(1)
expect {
Email::Processor.process!(mail2)
}.to change { EmailLog.count }.by(1)
end
end
end