Skip to content

Summarize dynamic DNS provider outages instead of showing raw responses - #408

Merged
drudge merged 3 commits into
mainfrom
claude/ddns-provider-errors-l8d7td
Oct 7, 2026
Merged

drudge merged 3 commits into
mainfrom
claude/ddns-provider-errors-l8d7td

Conversation

@drudge

@drudge drudge commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Requested by Nick · project thread

Before: when Cloudflare's API returned a 502, every configured record sent its own request in the same run, each one failed the same way, and the Dynamic DNS card showed every raw JSON body joined together. On a phone the text ran off the side of the card and pushed the facts grid out with it.

After: the first 429 or 5xx from a provider stops requests to that provider for the rest of the run. The card says something like home.penree.net A: Cloudflare had a temporary problem (502 Bad Gateway). Sable will try again. The redacted provider response is still available under View provider details, and the box wraps on narrow screens.

How

  • dnsprovider.APIError replaces the formatted string error for non-2xx responses. It carries the status code and any Retry-After value (seconds or HTTP date), and Temporary() returns true for 429 and 5xx. Error() produces the same text as before, with the body collapsed to one line so a joined error has one line per record.
  • dynamicdns: the record loop moves into publishRecords, which returns after the first temporary error from a provider. Other providers in the same run still publish. The next attempt waits for the longer of the existing backoff and the provider's Retry-After, capped at 30 minutes.
  • Console: dynamicDNSErrorDisplay summarizes each line of the error. A 429 reads as rate limiting and a 5xx as a temporary problem. A 4xx keeps the existing "rejected the request: messages (codes)" summary, and other statuses fall back to "returned 404 Not Found". Records that failed the same way share one summary line, which names three records and counts the rest. MCP's last_error uses the same summary.
  • CSS: .unifi-status > div gets min-width: 0, and the summary wraps anywhere and keeps line breaks.

go tool mage verify and gofmt -l . are clean. The new tests cover the APIError status and Retry-After handling, the provider short-circuit and retry timing, and the summary for Nick's actual error (four repeated 502 bodies), a 429, an HTML 404, a plain-text 403 with a token, and a mixed multi-provider error.

Screenshots are from a phone viewport (393px, dark) with the error from the report.

main branch branch, details open

The screenshots are added in one commit and removed in the next, so the squashed diff contains no images.


Generated by Claude Code

drudge added 3 commits October 7, 2026 15:01
When Cloudflare's API answered with a 502, every configured record made its
own request in the same run, each one failed the same way, and the console
showed all of the raw JSON bodies joined together, overflowing the card on a
phone.

A provider that answers 429 or 5xx now gets no more requests for the rest of
the run, and a Retry-After it sends sets the next attempt. Provider errors are
a typed dnsprovider.APIError that carries the status and that header.

The console summarizes each failure in one line, names a rate limit or a
provider-side failure as temporary, groups records that failed the same way,
and keeps the redacted provider response behind View provider details. The
error box wraps on narrow screens.
@drudge drudge self-assigned this Oct 7, 2026
@drudge
drudge merged commit 3f5ca02 into main Oct 7, 2026
4 checks passed
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.

1 participant