Skip to content

feat: surface network errors via a Result wrapper and shared callback - #918

Open
sinful1992 wants to merge 1 commit into
eddyizm:developmentfrom
sinful1992:feat/surface-network-errors
Open

feat: surface network errors via a Result wrapper and shared callback#918
sinful1992 wants to merge 1 commit into
eddyizm:developmentfrom
sinful1992:feat/surface-network-errors

Conversation

@sinful1992

Copy link
Copy Markdown
Contributor

Closes #912 (split out from #858).

Problem

Repositories use anonymous Retrofit callbacks whose onFailure is almost always empty (or a bare Log.d), and non-2xx responses in onResponse are ignored. When a request fails the LiveData never updates, so the user sees an empty list or an endless shimmer with no message and no way to tell why — a likely contributor to reports like #853.

Change

This ships the mechanism the issue describes, plus one real consumer, so the rollout to the other repositories can happen incrementally without a 90-file mega-PR.

Mechanism (subsonic/base/):

  • Resource<T> — Loading / Success / Error.
  • NetworkError — a categorised failure: UNREACHABLE (transport), SERVER_ERROR (non-2xx), INVALID_RESPONSE (2xx but missing/unparseable body), AUTH_FAILED (Subsonic failed with a credential/authorization code), API_ERROR (any other failed). This is the distinction a hardened login needs: wrong credentials vs server unreachable vs server returned garbage.
  • SubsonicCallback<T> — one Retrofit adapter that maps all of the above into a Resource in a single place; subclasses only implement extractData(SubsonicResponse). This is what removes the duplicated anonymous-callback boilerplate as callsites migrate.

First consumer — the login credential check:

  • SystemRepository.checkUserCredential now reports a Resource<Void>.
  • LoginFragment shows a specific message per category (wrong credentials / couldn't reach server / server error / unexpected response) instead of a raw exception string.
  • The now-unused SystemCallback interface is removed.

ErrorCode's constants are changed from var to const val so they're usable from Java (they were previously unreferenced).

Deliberately out of scope

The other ~95 enqueue callsites are not touched — they're the incremental follow-up the issue calls for. This PR keeps the diff reviewable and proves the mechanism end-to-end on the path #829 most needs it.

Milestone placement

Per the #858 thread, @eddyizm noted Tom may want to decide where this lands. It's broader than login (it's repository-wide infrastructure) but the login flow is its first consumer, matching the "build it first with LoginActivity as first consumer" plan in #829. Flagging for you both to slot as you see fit.

Testing

Not build-verified locally (no build env set up here) — CI/maintainer build appreciated. The login path is exercised by the existing server-tap flow; error categories map straight from Retrofit/Subsonic responses.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d05dbc0a-217c-4f02-bf17-a9ac1fb07a8a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sinful1992

Copy link
Copy Markdown
Contributor Author

Note: this and #917 (the #911 split) both touch LoginFragment.onServerClick a couple of lines apart, so they're conceptually stacked even though each is branched independently off development for a clean per-PR diff. Whichever merges first, I'll rebase the other — no action needed on your side.

Repository requests used anonymous Retrofit callbacks whose onFailure was
almost always empty and whose non-2xx responses were ignored, so a failed
request left the UI on an empty list or an endless shimmer with no message.

Introduce the shared mechanism the incremental rollout can build on:

- Resource<T> (Loading/Success/Error) plus a categorised NetworkError
  (UNREACHABLE / SERVER_ERROR / INVALID_RESPONSE / AUTH_FAILED / API_ERROR),
  so a caller can tell "wrong credentials" from "server unreachable" from
  "server returned garbage" — exactly what the hardened login flow (eddyizm#829)
  needs.
- SubsonicCallback<T>, one Retrofit adapter that maps transport failure,
  non-2xx, unparseable body and a "failed" Subsonic response into a Resource
  in a single place; subclasses only extract the payload they need.

Wire the login credential check as the first consumer: checkUserCredential
now reports a Resource, and LoginFragment shows a specific message per error
category instead of a raw exception string. The other ~95 repository
callsites are intentionally left for incremental follow-up.

ErrorCode constants become `const val` so they are usable from Java.

Closes eddyizm#912
@sinful1992
sinful1992 force-pushed the feat/surface-network-errors branch from c4675d7 to c9082c8 Compare July 21, 2026 22:14
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