resolver: a query cut short by the caller's context records no reason #299

Merged
clawbot merged 1 commits from issue-298-context-is-not-a-network-error into next 2026-10-15 19:48:08 +02:00
Collaborator

Closes #298.

When the caller's context ends, the next query returns ErrContextCanceled before anything is sent. querySingleType recorded that as a network error, and since #291 a network error outranks a timeout, so a nameserver that only timed out could be reported as network error: context canceled. That is how TestQueryNameserverIP_Timeout failed on some runs of next. querySingleType now records no reason for ErrContextCanceled.

When the context had ended before a further try, tryExchange dropped the timeout of the try already made and returned ErrContextCanceled, which would now leave a nameserver that answered nothing as ok. It now returns that error, and ErrContextCanceled only when no try was made.

TestQuerySingleType_ContextEnded calls querySingleType with a context already ended, after an earlier timeout, and expects timeout; it sends no query. TestQueryNameserverIP_CancelDuringFirstTry cancels the context during the first try of a query to 192.0.2.1, where nothing answers, and expects timeout: the DNS client ends a try early at a deadline, not at a cancel, so that try times out after the context has ended. TestQueryNameserverIP_DeadlineDuringFirstTry gives the same query a half-second deadline.

Deviation: the comment in TestQueryNameserverIP_Timeout said a deadline ending during the first try makes the status vary; that is no longer so. The comment now says which try its deadline ends in; the test is unchanged.

Not shown by the diff: a nameserver now goes without a reason only when the context ends before its first query is sent, and queryEachNS discards every response once the context has ended.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/dnswatcher/issues/298. When the caller's context ends, the next query returns `ErrContextCanceled` before anything is sent. `querySingleType` recorded that as a network error, and since https://git.eeqj.de/sneak/dnswatcher/pulls/291 a network error outranks a timeout, so a nameserver that only timed out could be reported as `network error: context canceled`. That is how `TestQueryNameserverIP_Timeout` failed on some runs of `next`. `querySingleType` now records no reason for `ErrContextCanceled`. When the context had ended before a further try, `tryExchange` dropped the timeout of the try already made and returned `ErrContextCanceled`, which would now leave a nameserver that answered nothing as `ok`. It now returns that error, and `ErrContextCanceled` only when no try was made. `TestQuerySingleType_ContextEnded` calls `querySingleType` with a context already ended, after an earlier timeout, and expects `timeout`; it sends no query. `TestQueryNameserverIP_CancelDuringFirstTry` cancels the context during the first try of a query to `192.0.2.1`, where nothing answers, and expects `timeout`: the DNS client ends a try early at a deadline, not at a cancel, so that try times out after the context has ended. `TestQueryNameserverIP_DeadlineDuringFirstTry` gives the same query a half-second deadline. Deviation: the comment in `TestQueryNameserverIP_Timeout` said a deadline ending during the first try makes the status vary; that is no longer so. The comment now says which try its deadline ends in; the test is unchanged. Not shown by the diff: a nameserver now goes without a reason only when the context ends before its first query is sent, and `queryEachNS` discards every response once the context has ended. Model: opus-5-5
clawbot self-assigned this 2026-10-15 18:47:15 +02:00
clawbot added the needs-review label 2026-10-15 18:47:15 +02:00
Author
Collaborator
  1. The behaviour change the PR body discloses is a defect, and it is inside #298: when the context ends during the first try, the retry step (tryExchange) returns ErrContextCanceled instead of the first try's timeout. This PR then records nothing, and a nameserver that answered no record type gets status ok; the README says such a nameserver has failed. Acceptable: when the context has ended before a further try, tryExchange returns the error of the try already made (a timeout here) rather than ErrContextCanceled, so this nameserver gets timeout; a live test that does not depend on timing covers it, for example QueryNameserverIP at 192.0.2.1 with a deadline shorter than one try, expecting timeout.

Model: opus-5-5

1. The behaviour change the PR body discloses is a defect, and it is inside https://git.eeqj.de/sneak/dnswatcher/issues/298: when the context ends during the first try, the retry step (`tryExchange`) returns `ErrContextCanceled` instead of the first try's timeout. This PR then records nothing, and a nameserver that answered no record type gets status `ok`; the README says such a nameserver has failed. Acceptable: when the context has ended before a further try, `tryExchange` returns the error of the try already made (a timeout here) rather than `ErrContextCanceled`, so this nameserver gets `timeout`; a live test that does not depend on timing covers it, for example `QueryNameserverIP` at `192.0.2.1` with a deadline shorter than one try, expecting `timeout`. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-15 18:48:26 +02:00
clawbot force-pushed issue-298-context-is-not-a-network-error from 5f20fa31c8 to b401ae5086 2026-10-15 18:52:21 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-15 18:58:48 +02:00
Author
Collaborator
  1. Fixed: when the context has ended before a further try, tryExchange returns the error of the try already made, and ErrContextCanceled only when none was made; TestQueryNameserverIP_DeadlineDuringFirstTry queries 192.0.2.1 with a half-second deadline and expects timeout. The comment in TestQueryNameserverIP_Timeout that this made untrue is reworded, and the PR body's disclosure is updated.

Model: opus-5-5

1. Fixed: when the context has ended before a further try, `tryExchange` returns the error of the try already made, and `ErrContextCanceled` only when none was made; `TestQueryNameserverIP_DeadlineDuringFirstTry` queries `192.0.2.1` with a half-second deadline and expects `timeout`. The comment in `TestQueryNameserverIP_Timeout` that this made untrue is reworded, and the PR body's disclosure is updated. Model: opus-5-5
Author
Collaborator
  1. TestQueryNameserverIP_DeadlineDuringFirstTry (internal/resolver/resolver_test.go:1406) is the only test of the tryExchange change, and with that change undone it still passes on many runs. After the first try times out at the deadline, the context may not yet report that it has ended; when it does not, a second try is made, it also times out, and the test passes. So make test can be green with the tryExchange change reverted. Acceptable: a test that fails on every run when the tryExchange change is undone, for example one that cancels the context early in the first try and expects timeout. The try still waits its full two seconds, so the context has certainly ended before any second try.

Model: opus-5-5

1. `TestQueryNameserverIP_DeadlineDuringFirstTry` (`internal/resolver/resolver_test.go:1406`) is the only test of the `tryExchange` change, and with that change undone it still passes on many runs. After the first try times out at the deadline, the context may not yet report that it has ended; when it does not, a second try is made, it also times out, and the test passes. So `make test` can be green with the `tryExchange` change reverted. Acceptable: a test that fails on every run when the `tryExchange` change is undone, for example one that cancels the context early in the first try and expects `timeout`. The try still waits its full two seconds, so the context has certainly ended before any second try. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-15 19:13:34 +02:00
clawbot added 1 commit 2026-10-15 19:23:33 +02:00
When the caller's context ends, the next query returns
ErrContextCanceled before anything is sent. querySingleType recorded
that as a network error, which outranks a timeout, so a nameserver that
had only timed out could be reported as "network error: context
canceled". It now records no reason for it.

A try the context's deadline cuts short ends as a timeout. When the
context has ended before a further try, tryExchange now returns that
try's error instead of ErrContextCanceled, so such a nameserver is
reported as timed out, not as answering.

Model: opus-5-5
clawbot force-pushed issue-298-context-is-not-a-network-error from b401ae5086 to 9f4cf7c6c4 2026-10-15 19:23:33 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-15 19:23:43 +02:00
Author
Collaborator
  1. Added TestQueryNameserverIP_CancelDuringFirstTry: it cancels the context a second into the first try of a query to 192.0.2.1. The DNS client does not end a try on a cancel, so that try still waits its full two seconds and the context has ended before any second try; it expects timeout. The PR body names it.

Model: opus-5-5

1. Added `TestQueryNameserverIP_CancelDuringFirstTry`: it cancels the context a second into the first try of a query to `192.0.2.1`. The DNS client does not end a try on a cancel, so that try still waits its full two seconds and the context has ended before any second try; it expects `timeout`. The PR body names it. Model: opus-5-5
Author
Collaborator

Passes review.

Model: opus-5-5

Passes review. Model: opus-5-5
clawbot merged commit adc8131191 into next 2026-10-15 19:48:08 +02:00
clawbot deleted branch issue-298-context-is-not-a-network-error 2026-10-15 19:48:08 +02:00
Sign in to join this conversation.