watcher: a lookup cut short by shutdown is not logged as an error (closes #229)
check / check (push) Canceled after 0s

Stopping dnswatcher during a DNS check logged every lookup the stop cut
short as an error, "context canceled". The four places in the watcher
that log a failed lookup, checkDomain, checkHostname,
resolveNameserverAddresses and resolveCNAMEAddresses, now do it through
logFailedLookup, which logs nothing when the watcher's context was
cancelled. It asks the context, not the lookup's error: the resolver
reports a cancelled lookup with its own error, which does not wrap
context.Canceled. A context whose deadline passed is not cancelled, so a
lookup that ran out of time is still logged. The tests run each of these
lookups on a cancelled context and on one whose deadline passed; neither
sends a query.

Model: opus-5-5
This commit was merged in pull request #237.
This commit is contained in:
2026-10-02 08:56:52 +02:00
parent f99de191c0
commit b047c3c64c
4 changed files with 104 additions and 4 deletions
+24 -4
View File
@@ -2,6 +2,7 @@ package watcher
import (
"context"
"errors"
"fmt"
"log/slog"
"slices"
@@ -213,13 +214,29 @@ func (w *Watcher) runDNSChecks(ctx context.Context) {
}
}
// logFailedLookup logs a failed DNS lookup at error level, unless ctx
// was cancelled: shutdown cancels it, and a lookup it cut short did not
// fail. A lookup that ran out of time did fail, so it is logged.
func (w *Watcher) logFailedLookup(
ctx context.Context,
msg string,
args ...any,
) {
if errors.Is(ctx.Err(), context.Canceled) {
return
}
w.log.Error(msg, args...)
}
func (w *Watcher) checkDomain(
ctx context.Context,
domain string,
) {
nameservers, err := w.resolver.LookupNS(ctx, domain)
if err != nil {
w.log.Error(
w.logFailedLookup(
ctx,
"failed to lookup NS",
"domain", domain,
"error", err,
@@ -320,7 +337,8 @@ func (w *Watcher) resolveNameserverAddresses(
continue
}
w.log.Error(
w.logFailedLookup(
ctx,
"no addresses found for nameserver",
"nameserver", ns,
"error", err,
@@ -372,7 +390,8 @@ func (w *Watcher) checkHostname(
) {
results, err := w.resolver.LookupAllRecords(ctx, hostname)
if err != nil {
w.log.Error(
w.logFailedLookup(
ctx,
"failed to lookup records",
"hostname", hostname,
"error", err,
@@ -455,7 +474,8 @@ func (w *Watcher) resolveCNAMEAddresses(
for target := range targets {
ips, err := w.resolver.ResolveIPAddresses(ctx, target)
if err != nil {
w.log.Error(
w.logFailedLookup(
ctx,
"failed to follow CNAME",
"hostname", hostname,
"target", target,