Compare commits

..
1 Commits
Author SHA1 Message Date
sneak bd728e37b1 notify: the log names a notification endpoint, not its webhook URL (closes #288)
check / check (push) Canceled after 0s
With debug logging on, each delivery logged the full Slack, Mattermost
or ntfy URL, whose path or query lets anyone who has it post to the
channel or topic. The two debug lines now give the endpoint's name and
the title; sendSlack is told which of Slack or Mattermost it sends to.
A webhook URL that does not parse gave a startup error quoting the
whole URL; it now gives only the reason. Errors from a failed request
come from the transport, not from an HTTP client, and carry no part of
the path or query; a test now checks that too.

Model: opus-5-5
2026-10-15 11:42:05 +00:00
+9 -22
View File
@@ -1129,7 +1129,6 @@ type logRecord struct {
Msg string `json:"msg"`
Endpoint string `json:"endpoint"`
Title string `json:"title"`
Error string `json:"error"`
}
// parseLog decodes each line of a JSON log.
@@ -1226,8 +1225,7 @@ func TestSendNotificationDebugLogOmitsWebhookURL(t *testing.T) {
// TestSendNotificationErrorLogOmitsWebhookURL checks that a delivery
// to each endpoint that cannot connect logs the transport's error,
// which names the refused connection, on its retry line and on its
// final failure line, and that no line holds any part of the URL's
// on every attempt and at the end, without any part of the URL's
// path or query.
func TestSendNotificationErrorLogOmitsWebhookURL(t *testing.T) {
t.Parallel()
@@ -1241,31 +1239,20 @@ func TestSendNotificationErrorLogOmitsWebhookURL(t *testing.T) {
assertNoWebhookSecret(t, logs)
// For each endpoint, the messages of its lines whose error names
// the refused connection, in the order they were logged.
got := map[string][]string{}
var failed []string
for _, record := range parseLog(t, logs) {
if strings.Contains(record.Error, "connection refused") {
got[record.Endpoint] = append(
got[record.Endpoint], record.Msg,
)
if record.Msg == "failed to send notification after retries" {
failed = append(failed, record.Endpoint)
}
}
lines := []string{
"notification delivery failed, retrying",
"failed to send notification after retries",
}
want := map[string][]string{
endpointNtfy: lines,
endpointSlack: lines,
endpointMattermost: lines,
}
slices.Sort(failed)
if !maps.EqualFunc(got, want, slices.Equal) {
t.Errorf("lines whose error names the refused connection = %v, "+
"want %v", got, want)
want := []string{endpointMattermost, endpointNtfy, endpointSlack}
if !slices.Equal(failed, want) {
t.Errorf("endpoints that logged a failure = %v, want %v",
failed, want)
}
}