Skip to content

Commit e47b4a5

Browse files
committed
Add a field to track errors of notify_by_email
1 parent 19d7af7 commit e47b4a5

9 files changed

Lines changed: 69 additions & 19 deletions

File tree

app/controllers/api/v2/version_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def features
2121
},
2222
pushes: {
2323
enabled: true,
24-
email_auto_dispatch: Settings.mail.smtp_address.present?,
24+
email_auto_dispatch: Settings.notify_by_email_available?,
2525
file_attachments: {
2626
enabled: Settings.enable_file_pushes,
2727
requires_authentication: true

app/jobs/send_push_created_email_job.rb

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,25 @@ class SendPushCreatedEmailJob < ApplicationJob
44
queue_as :default
55

66
def perform(notify_by_email_id)
7-
notify_by_email = NotifyByEmail.find_by!(id: notify_by_email_id)
7+
notify_by_email = NotifyByEmail.find_by(id: notify_by_email_id)
8+
9+
if notify_by_email.nil?
10+
Rails.logger.error "[SendPushCreatedEmailJob] NotifyByEmail not found: #{notify_by_email_id}"
11+
12+
return
13+
end
14+
15+
if notify_by_email.recipients.blank?
16+
notify_by_email.update(status: :failed, error_message: _("No recipients found."))
17+
18+
return
19+
end
20+
21+
unless Settings.notify_by_email_available?
22+
notify_by_email.update(status: :failed, error_message: _("Email notifications are not available."))
23+
24+
return
25+
end
826

927
return unless notify_by_email.pending?
1028

@@ -14,6 +32,12 @@ def perform(notify_by_email_id)
1432
locale = notify_by_email.locale
1533
recipients = notify_by_email.recipients.split(",").map(&:strip)
1634

35+
if push.expired?
36+
notify_by_email.update(status: :failed, error_message: _("Push already expired."))
37+
38+
return
39+
end
40+
1741
successful_sends = []
1842
recipients.each do |recipient|
1943
mail = PushCreatedMailer.with(push: push, recipient: recipient, locale: locale).notify
@@ -23,14 +47,19 @@ def perform(notify_by_email_id)
2347
Rails.logger.error "[SendPushCreatedEmailJob] Error sending email: #{e.message}"
2448
end
2549

26-
status = if successful_sends.size == recipients.size
27-
:completed
50+
status, error_message = if successful_sends.size == recipients.size
51+
[:completed, nil]
2852
elsif successful_sends.empty?
29-
:fully_failed
53+
[:failed, I18n._("No emails were sent successfully.")]
3054
else
31-
:partially_failed
55+
[:partially_failed, I18n._("Some emails could not be sent.")]
3256
end
3357

34-
notify_by_email.update!(successful_sends: successful_sends.join(","), status: status, proceed_at: Time.current)
58+
notify_by_email.update!(successful_sends: successful_sends.join(","), status: status, error_message: error_message, proceed_at: Time.current)
3559
end
60+
61+
rescue => e
62+
Rails.logger.error "[SendPushCreatedEmailJob] Error sending email: #{e.message}"
63+
64+
notify_by_email.update(status: :failed, error_message: e.message)
3665
end

app/models/concerns/pwpush/notifiable_by_email.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module NotifiableByEmail
1818
validate :notify_by_email_limit
1919

2020
def notify_by_email_available?(cur_user)
21-
Settings.mail.smtp_address.present? && !Settings.disable_logins && cur_user.present? && (!persisted? || (cur_user == user))
21+
Settings.notify_by_email_available? && cur_user.present? && (!persisted? || (cur_user == user))
2222
end
2323
end
2424

@@ -46,7 +46,7 @@ def total_notify_by_emails_count
4646
end
4747

4848
def notify_by_email_availability
49-
if Settings.disable_logins || Settings.mail.smtp_address.blank?
49+
unless Settings.notify_by_email_available?
5050
errors.add(:base, _("Notifying by email is not available"))
5151
end
5252

app/models/notify_by_email.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
class NotifyByEmail < ApplicationRecord
44
attr_readonly :recipients, :recipients_count, :locale
55

6-
enum :status, [:pending, :processing, :completed, :partially_failed, :fully_failed], validate: true
6+
enum :status, [:pending, :processing, :completed, :partially_failed, :failed], validate: true
77

88
before_create :set_recipients_count
99

1010
belongs_to :audit_log
1111

1212
has_one :push, through: :audit_log
13-
has_encrypted :recipients, :locale, :successful_sends
13+
has_encrypted :recipients, :locale, :successful_sends, :error
1414

1515
private
1616

app/views/audit_logs/_log_creation_email_send.html.erb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
when "completed" then "list-group-item-success"
55
when "processing", "pending" then "list-group-item-info"
66
when "partially_failed" then "list-group-item-warning"
7-
when "fully_failed" then "list-group-item-danger"
7+
when "failed" then "list-group-item-danger"
88
else "list-group-item-info"
99
end %>
1010

@@ -13,7 +13,7 @@
1313
when "processing" then "bi-hourglass-split"
1414
when "pending" then "bi-envelope"
1515
when "partially_failed" then "bi-envelope-exclamation"
16-
when "fully_failed" then "bi-envelope-x"
16+
when "failed" then "bi-envelope-x"
1717
else "bi-envelope"
1818
end %>
1919

@@ -39,6 +39,12 @@
3939
</div>
4040
<% end %>
4141

42+
<% if notify_by_email.error_message.present? %>
43+
<div>
44+
<strong><%= _('Error:') %></strong> <span><%= notify_by_email.error_message %></span>
45+
</div>
46+
<% end %>
47+
4248
<div>
4349
<strong><%= _('Proceed At:') %></strong> <span><%= notify_by_email.proceed_at.blank? ? _('Not yet') : local_time(notify_by_email.proceed_at, :long) %></span>
4450
</div>

config/initializers/config.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,9 @@
5858
#
5959
# config.evaluate_erb_yaml = true
6060
end
61+
62+
Rails.application.config.to_prepare do
63+
Settings.define_singleton_method(:notify_by_email_available?) do
64+
!Settings.disable_logins && Settings.mail&.smtp_address.present?
65+
end
66+
end

db/migrate/20260427190300_create_notify_by_emails.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def change
99
t.text :successful_sends_ciphertext
1010
t.string :locale_ciphertext
1111
t.integer :status, default: 0, null: false
12+
t.text :error_message
1213

1314
t.datetime :proceed_at
1415
t.timestamps

db/schema.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
create_table "notify_by_emails", force: :cascade do |t|
6666
t.integer "audit_log_id", null: false
6767
t.datetime "created_at", null: false
68+
t.text "error_message"
6869
t.string "locale_ciphertext"
6970
t.datetime "proceed_at"
7071
t.text "recipients_ciphertext", null: false

test/unit/send_push_created_email_job_test.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class SendPushCreatedEmailJobTest < ActiveJob::TestCase
2828
assert_equal "one@example.com", @notify_by_email.successful_sends
2929
end
3030

31-
test "perform update notify_by_email status to fully_failed after sending" do
31+
test "perform update notify_by_email status to failed after sending" do
3232
failing_mail = Minitest::Mock.new
3333
failing_mail.expect(:deliver_now, -> { raise StandardError, "test error" })
3434

@@ -37,8 +37,9 @@ class SendPushCreatedEmailJobTest < ActiveJob::TestCase
3737
end
3838

3939
@notify_by_email.reload
40-
assert_equal "fully_failed", @notify_by_email.status
40+
assert_equal "failed", @notify_by_email.status
4141
assert_equal "", @notify_by_email.successful_sends
42+
assert_equal "No emails were sent successfully.", @notify_by_email.error_message
4243
end
4344

4445
test "perform does not send mail when notify_by_email is not pending" do
@@ -54,15 +55,21 @@ class SendPushCreatedEmailJobTest < ActiveJob::TestCase
5455
SendPushCreatedEmailJob.perform_now(@notify_by_email.id)
5556

5657
@notify_by_email.reload
57-
assert_equal "completed", @notify_by_email.status
58+
assert_equal "failed", @notify_by_email.status
5859
assert @notify_by_email.successful_sends.blank?
60+
assert_equal "No recipients found.", @notify_by_email.error_message
5961
end
6062

61-
test "perform raises an error if notify_by_email is not found" do
62-
assert_raise ActiveRecord::RecordNotFound do
63-
invalid_id = -1
63+
test "perform logs error and does not send mail if notify_by_email is not found" do
64+
invalid_id = -1
65+
logger = Minitest::Mock.new
66+
logger.expect(:error, nil, ["[SendPushCreatedEmailJob] NotifyByEmail not found: #{invalid_id}"])
67+
68+
Rails.stub(:logger, logger) do
6469
SendPushCreatedEmailJob.perform_now(invalid_id)
6570
end
71+
72+
assert logger.verify
6673
end
6774

6875
test "perform uses default queue" do

0 commit comments

Comments
 (0)