Skip to content

Alert ergonomics - #291

Open
lerlacher-fm wants to merge 2 commits into
fastmail:mainfrom
lerlacher-fm:le-plat-4458-alerts-ergonomics
Open

Alert ergonomics#291
lerlacher-fm wants to merge 2 commits into
fastmail:mainfrom
lerlacher-fm:le-plat-4458-alerts-ergonomics

Conversation

@lerlacher-fm

@lerlacher-fm lerlacher-fm commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Two changes to PagerDuty reactor commands:

  • the only thing you can ack is 'all': There is no point in enforcing 'ack all'. Any ack shall ack.
  • snooze all: If 'all' is passed instead of an incident number, snooze everything

There is no point in enforcing 'ack all'. Any ack shall ack.
If 'all' is passed instead of an incident number, snooze everything
@lerlacher-fm
lerlacher-fm force-pushed the le-plat-4458-alerts-ergonomics branch from 0729558 to 830cd26 Compare August 12, 2026 22:25
@lerlacher-fm

Copy link
Copy Markdown
Contributor Author

@rjbs Before I spend time testing the implementation, do you have any objections to the behavior change I'm proposing here?

@rjbs

rjbs commented Aug 12, 2026

Copy link
Copy Markdown
Member

Nope!

@lerlacher-fm

Copy link
Copy Markdown
Contributor Author

Testing seems ok:

snooze #41478 for 1 hour
LOG | message event from term-rw/u:lerlacher: snooze #41478 for 1 hour
╭─────┤ term-rw!sysop ├───────────────────────────────────────────────────────╮
│ Snoozed incidents for 1 hour: 
│ #Q0X18OP6VRORZF (phl-root-02 - movemate is restarting too fast)
╰─────────────────────────────────────────────────────────────────────────────╯
snooze all for 48 hours
LOG | message event from term-rw/u:lerlacher: snooze all for 48 hours
╭─────┤ term-rw!sysop ├───────────────────────────────────────────────────────╮
│ Snoozed incidents for 2 days: 
│ #Q0X18OP6VRORZF (phl-root-02 - movemate is restarting too fast)
╰─────────────────────────────────────────────────────────────────────────────╯

ack
LOG | message event from term-rw/u:lerlacher: ack
LOG | PagerDuty: acking incidents: {{[]}}
╭─────┤ term-rw!sysop ├───────────────────────────────────────────────────────╮
│ Successfully acked 0 incidents. Good luck!
╰─────────────────────────────────────────────────────────────────────────────╯
ack all
LOG | message event from term-rw/u:lerlacher: ack all
LOG | PagerDuty: acking incidents: {{[]}}
╭─────┤ term-rw!sysop ├───────────────────────────────────────────────────────╮
│ Successfully acked 0 incidents. Good luck!
╰─────────────────────────────────────────────────────────────────────────────╯
ack nothing
LOG | message event from term-rw/u:lerlacher: ack nothing
LOG | PagerDuty: acking incidents: {{[]}}
╭─────┤ term-rw!sysop ├───────────────────────────────────────────────────────╮
│ Successfully acked 0 incidents. Good luck!
╰─────────────────────────────────────────────────────────────────────────────╯

@lerlacher-fm
lerlacher-fm marked this pull request as ready for review August 13, 2026 01:28
Comment on lines +618 to +628
my $res = await $self->_pd_request_for_user(
$event->from_user,
POST => "/incidents/$id/snooze",
{ duration => $seconds }
);

if (my $incident = $res->{incident}) {
my $title = $incident->{title};
push @snoozed, "#$id ($title)";
} else {
push @errors, $res->{message};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_pd_request fails the future on non-2xx, so it never returns a hash with message — the else at 628 is unreachable, and the bare await propagates the failure out of the command. snooze all for 1h where #42 got resolved by someone else mid-batch: #41 stays snoozed in PD, #43 is never attempted, and the user just gets "My PagerDuty reactor crashed (in the background)".

Comment on lines +632 to +635
my $reply = sprintf("Snoozed incidents for %s: \n%s", duration($seconds), join("\n", @snoozed));

return await $event->reply(
"Something went wrong talking to PagerDuty; they said: $msg"
);
if (@errors) {
my $reply .= sprintf("\n\nUnfortunately we also received errors:\n%s", join("\n", @errors));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my $reply at 635 declares a fresh variable inside the if, so the error text goes to a throwaway and never reaches the user.

command ack => {
help => '*ack all*: acknowledge all triggered alerts in PagerDuty',
help => '*ack*: acknowledge all triggered alerts in PagerDuty',
} => async sub ($self, $event, $rest) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$rest is bound here and never read again, so ack 42 acks the whole board silently — same for ack mine, ack banana. Bare ack meaning "all" is right, but acking all when trying to ack one is probably bad.

Comment on lines +604 to +605
# select a single incident if we
my @relevant = ($incident =~ /\d+/) ? grep {; $_->{incident_number} == $incident } @incidents : @incidents;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/\d+/ isn't anchored, so it's asking "is there a digit anywhere" rather than "is this an incident number". mine has no digit, falls through to the all-branch.

snooze all for DURATION',
} => async sub ($self, $event, $rest) {
my ($num, $dur) = $rest =~ /^#?(\d+)\s+for\s+(.*)/i;
my ($incident, $dur) = $rest =~ /^#?(\S+)\s+for\s+(.*)/i;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bare snooze gets $rest = undef from CommandPost, so this matches a regex against undef and probably logs a warning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants