Skip to content

Improve error surfacing when NEXT_PUBLIC_CORE_API_URL is misconfigured (#228)#313

Merged
Lakes41 merged 1 commit into
Adamantine-guild:mainfrom
temisan0x:228-config-error-surfacing
Jul 24, 2026
Merged

Improve error surfacing when NEXT_PUBLIC_CORE_API_URL is misconfigured (#228)#313
Lakes41 merged 1 commit into
Adamantine-guild:mainfrom
temisan0x:228-config-error-surfacing

Conversation

@temisan0x

@temisan0x temisan0x commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Closes #228.

Addresses both failure modes for a misconfigured
NEXT_PUBLIC_CORE_API_URL: an invalid URL at startup, and a syntactically
valid but unreachable backend at runtime.

Investigation

Before writing any code, I traced through the existing config/error/offline
infrastructure to see what already existed vs. what was actually missing:

  • Invalid URL formatlib/config.ts already throws a ConfigError at
    module-import time that names NEXT_PUBLIC_CORE_API_URL explicitly and
    explains the expected format. No error.tsx / global-error.tsx exists in
    app/, so this surfaces as a raw build/startup failure rather than a
    formatted page — documented as expected behavior rather than "fixed",
    since adding a custom error boundary for module-load-time errors is a
    larger, riskier change than this issue calls for.
  • Unreachable-but-valid URL — this was the real gap. lib/api/backendStatus.ts
    already had an ensureOnline() health check and a backendOnline reactive
    flag, and SyncStatusBanner was already wired to read from it via
    useSyncStatus(). But ensureOnline() was only ever called lazily,
    inside two API call sites in lib/api/live.ts — meaning a broken backend
    URL produced no visible signal at all until a user happened to trigger
    an action that hit the API. Additionally, the banner had no way to
    distinguish "your browser is offline" from "the configured backend is
    unreachable" — both showed the same generic offline copy.

Changes

  • components/backend-health-check.tsx (new)
    Invisible client component, same pattern as the existing SwRegistrar,
    that calls ensureOnline() once on mount. This is what makes the
    unreachable-backend case surface immediately on load instead of waiting
    for a user action to fail.

  • app/layout.tsx
    Mounts <BackendHealthCheck /> in the root layout, alongside the existing
    <SwRegistrar /> / <SyncStatusBanner />.

  • lib/offline/use-sync-status.ts
    Added a new isBackendReachable field to SyncStatus, separate from the
    existing combined isOnline flag, so the UI can tell the two failure modes
    apart.

  • components/ui/sync-status-banner.tsx
    Added a new banner state: when the browser is online but
    isBackendReachable is false, shows a distinct message — "Can't reach
    the backend service... check that NEXT_PUBLIC_CORE_API_URL is set
    correctly"
    — instead of the generic offline copy. Clears automatically
    once ensureOnline() succeeds again (reactive via the existing
    backendOnline.subscribe() mechanism).

  • docs/deployment.md
    New "Troubleshooting" section covering both failure modes: invalid URL
    (build/startup failure, what the error looks like) and valid-but-unreachable
    URL (what the banner looks like, how to diagnose it).

Acceptance criteria

  • Invalid URL format produces a clear startup error naming the variable
    and issue — pre-existing, verified and documented rather than
    re-implemented.
  • Unreachable-but-valid URL produces a visible in-app banner rather than
    silent failure — previously only reactive on user action; now also
    proactive on load, with a message distinct from generic offline state.
  • Documented in docs/deployment.md's troubleshooting section.

Notes for reviewers

  • No changes to lib/config.ts — its existing ConfigError messaging was
    already good; verified this by reading it directly rather than assuming.
  • The banner is not dismissible (checked before documenting it as such,
    then corrected the docs) — it clears automatically when the backend
    becomes reachable again.
  • Happy to add a lightweight error.tsx for the invalid-URL case in a
    follow-up if maintainers want that too — kept out of this PR since it
    wasn't explicitly required by the acceptance criteria and is a bigger
    surface area to review.

@Lakes41
Lakes41 merged commit 552de7a into Adamantine-guild:main Jul 24, 2026
1 check 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.

Improve error surfacing when NEXT_PUBLIC_CORE_API_URL is misconfigured

2 participants