Repository navigation
fix(cp): make pdbFetch throw instead of returning null - #299
Merged
Merged
Conversation
netravnen
force-pushed
the
fix/cp-pdbfetch-throws
branch
from
August 19, 2026 22:27
b462723 to
728af2b
Compare
netravnen
force-pushed
the
fix/cp-pdbfetch-throws
branch
from
August 19, 2026 22:28
728af2b to
a03774d
Compare
netravnen
force-pushed
the
fix/cp-pdbfetch-throws
branch
from
August 19, 2026 22:29
a03774d to
3f44b1c
Compare
pdbFetch resolved to null for every failure mode -- HTTP error, JSON parse failure, transport error and timeout alike. Because null is also a plausible "nothing here" value, that silently turned the error handling written around it into dead code. fetchRecentNetixlanChanges shows the cost. Its first try block always reached its return, so both its catch and the entire client-side filtering fallback beneath it were unreachable. A rejected updated__gte filter therefore reported "0 rows, no error" -- an admin verifying an IXLAN renumber would read that as "nothing changed" rather than "the check did not run". The code was written expecting pdbFetch to throw; the null return was the deviation, so this restores the surrounding design rather than imposing a new one. Changes: - Added makePdbFetchError(url, detail), producing a PdbFetchError carrying name/status/url/detail so callers can branch on the failure rather than guess at it. - All seven null exits (three same-origin, four cross-origin) now throw or reject. recordFetchFailure diagnostics are unchanged; the same-origin catch rethrows an existing PdbFetchError untouched so status and type survive. - Reviewed all 21 call sites. Eighteen already had an enclosing catch that was dead code and is now live; each was read to confirm it does something sensible (they return error-carrying result objects). - Three callers deliberately want a sentinel, so they catch at their own boundary and say why: requestJson (getBootstrap carries an explicit "@ai Preserve ... null-on-failure" contract for graceful RDAP degradation), and the GraphQL/REST network-name batch fetchers, whose null and [] returns are fallback signals their paging loop depends on. - Guarded the networkixlan toolbar's fire-and-forget `void (async ...)()`, which had no handler at all. A throw there would have become an unhandled rejection; the org/ix links are decorative, so a failed lookup now logs via dbg and omits them, matching prior behavior. - Documented both rules in docs/CONVENTIONS.md. Security: - N/A directly, but it removes a class of silent failure in the flows that verify destructive work. The renumber verification report can no longer claim zero changes when it never successfully queried. Testing: - node --test from user.js/: 500 tests, 499 pass, 1 skipped (live tests are opt-in), up from 493/492. - Added tests/cp-pdbfetch-errors.test.js covering the typed rejection and its status/url/detail, that success still resolves to a parsed payload, and that the revived fallback both runs and reports source "client-filter" -- a path that could not previously execute. - Confirmed not vacuous: restoring the null return on HTTP error fails 6 of the 7 new cases. - Re-audited every call site afterwards; none is left without a handler. Backwards Compatibility: - Behavior on success is identical. - Behavior on failure changes by design: callers that previously saw null now see a rejection. Every site was inspected and either already handled it or was updated, so no caller observes a different outcome than before -- except fetchRecentNetixlanChanges, which now actually falls back. Assisted-by: Claude:claude-opus-5
netravnen
force-pushed
the
fix/cp-pdbfetch-throws
branch
from
August 19, 2026 22:31
3f44b1c to
12fa9de
Compare
netravnen
marked this pull request as ready for review
August 19, 2026 23:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pdbFetch resolved to null for every failure mode -- HTTP error, JSON parse
failure, transport error and timeout alike. Because null is also a
plausible "nothing here" value, that silently turned the error handling
written around it into dead code.
fetchRecentNetixlanChanges shows the cost. Its first try block always
reached its return, so both its catch and the entire client-side filtering
fallback beneath it were unreachable. A rejected updated__gte filter
therefore reported "0 rows, no error" -- an admin verifying an IXLAN
renumber would read that as "nothing changed" rather than "the check did
not run". The code was written expecting pdbFetch to throw; the null
return was the deviation, so this restores the surrounding design rather
than imposing a new one.
Changes:
name/status/url/detail so callers can branch on the failure rather than
guess at it.
reject. recordFetchFailure diagnostics are unchanged; the same-origin
catch rethrows an existing PdbFetchError untouched so status and type
survive.
was dead code and is now live; each was read to confirm it does something
sensible (they return error-carrying result objects).
boundary and say why: requestJson (getBootstrap carries an explicit "@ai
Preserve ... null-on-failure" contract for graceful RDAP degradation),
and the GraphQL/REST network-name batch fetchers, whose null and []
returns are fallback signals their paging loop depends on.
void (async ...)(),which had no handler at all. A throw there would have become an unhandled
rejection; the org/ix links are decorative, so a failed lookup now logs
via dbg and omits them, matching prior behavior.
Security:
verify destructive work. The renumber verification report can no longer
claim zero changes when it never successfully queried.
Testing:
opt-in), up from 493/492.
its status/url/detail, that success still resolves to a parsed payload,
and that the revived fallback both runs and reports source
"client-filter" -- a path that could not previously execute.
the 7 new cases.
Backwards Compatibility:
now see a rejection. Every site was inspected and either already handled
it or was updated, so no caller observes a different outcome than before
-- except fetchRecentNetixlanChanges, which now actually falls back.
Assisted-by: Claude:claude-opus-5
Stack created with GitHub Stacks CLI • Give Feedback 💬