mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
When automations fail silently (e.g., PM sending blocked due to
validation errors), admins have no visibility into what's going wrong.
This leaves them guessing why their automations aren't working as
expected.
This change addresses the problem in three ways:
1. Error tracking in automation stats
The Stat model now tracks `total_errors` alongside existing run metrics.
When an automation raises an exception during execution, it's caught and
counted. This gives admins visibility into which automations are
experiencing problems.
2. Centralized logging module
Created `DiscourseAutomation::Logger` to replace scattered
`Rails.logger.warn("[discourse-automation] ...")` calls throughout the
codebase. This eliminates the fragile manual prefix pattern and ensures
consistent log formatting across all automation code. All existing
logging calls have been migrated to use this module.
3. Error count display in admin UI
The automation list now shows recent error counts next to run
statistics. Clicking the error count links directly to `/logs` filtered
for discourse-automation entries, making it easy to investigate
failures. The link uses `data-auto-route="true"` to ensure proper
navigation outside Ember's client-side router.
<img width="1397" height="1041" alt="2026-01-01 @ 23 03 34"
src="https://github.com/user-attachments/assets/6a6733f1-999c-44de-ab04-78dd764a1a43"
/>
Ref - https://meta.discourse.org/t/389922
73 lines
2.4 KiB
Ruby
Vendored
73 lines
2.4 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
DiscourseAutomation::Scriptable.add(DiscourseAutomation::Scripts::GIFT_EXCHANGE) do
|
|
placeholder :year
|
|
placeholder :giftee_username
|
|
placeholder :gifter_username
|
|
|
|
field :giftee_assignment_messages, component: :pms, accepts_placeholders: true, required: true
|
|
field :gift_exchangers_group, component: :group, required: true
|
|
|
|
version 17
|
|
|
|
triggerables %i[point_in_time]
|
|
|
|
script do |_, fields, automation|
|
|
now = Time.zone.now
|
|
group_id = fields.dig("gift_exchangers_group", "value")
|
|
|
|
unless group = Group.find_by(id: group_id)
|
|
DiscourseAutomation::Logger.warn("Couldn't find group with id #{group_id}")
|
|
next
|
|
end
|
|
|
|
cf_name = "#{group.name}-gifts-were-exchanged-#{automation.id}-#{version}-#{now.year}"
|
|
if group.custom_fields[cf_name].present?
|
|
DiscourseAutomation::Logger.warn(
|
|
"Gift exchange script has already been run on #{cf_name} this year #{now.year} for this script version #{version}",
|
|
)
|
|
next
|
|
end
|
|
|
|
usernames = group.users.pluck(:username)
|
|
|
|
if usernames.size < 3
|
|
DiscourseAutomation::Logger.warn("Gift exchange needs at least 3 users in a group")
|
|
next
|
|
end
|
|
|
|
usernames.shuffle!
|
|
usernames << usernames[0]
|
|
|
|
# shuffle the pairs to prevent prying eyes to identify matches by looking at the timestamps of the topics
|
|
pairs = usernames.each_cons(2).to_a.shuffle
|
|
|
|
pairs.each do |gifter, giftee|
|
|
placeholders = { year: now.year.to_s, gifter_username: gifter, giftee_username: giftee }
|
|
|
|
Array(fields.dig("giftee_assignment_messages", "value")).each do |giftee_assignment_message|
|
|
if giftee_assignment_message["title"].blank?
|
|
DiscourseAutomation::Logger.warn("Gift exchange requires a title for the PM")
|
|
next
|
|
end
|
|
|
|
if giftee_assignment_message["raw"].blank?
|
|
DiscourseAutomation::Logger.warn("Gift exchange requires a raw for the PM")
|
|
next
|
|
end
|
|
|
|
raw = utils.apply_placeholders(giftee_assignment_message["raw"], placeholders)
|
|
title = utils.apply_placeholders(giftee_assignment_message["title"], placeholders)
|
|
|
|
utils.send_pm(
|
|
{ target_usernames: Array(gifter), title: title, raw: raw },
|
|
delay: giftee_assignment_message["delay"],
|
|
automation_id: automation.id,
|
|
)
|
|
end
|
|
end
|
|
|
|
group.custom_fields[cf_name] = true
|
|
group.save_custom_fields
|
|
end
|
|
end
|