Repository navigation
Conversation
…e user An expired/revoked bearer left the Roku client unusable: every /api/v1 call 401'd, the guide showed "Check your connection", and Settings/Account in the sidebar silently did nothing — so the user could not even sign out. - GuideSidebar built its item list only on a packages/lens change. With /api/v1/packages failing (and `lens` never changing from its "all" default), m.items stayed empty and onActivate dropped every OK. Build it in init so the action circles always work. - Classify request failures centrally (Api.errorKind → network / auth / forbidden / server / client) and carry `kind` on every rejection. - A definitive 401 from a bearer /api/v1 request (for the current token) is signalled once from Api_onResponse; MainScene clears only the token, keeps the server URL, tears down the player and routes to Login with a "session expired" notice. Idempotent across the parallel 401s; network failures never clear credentials. Matches tv-web's forced sign-out on a guide 401. - Guide first-load failures say what failed and retry (OK, or the 60s timer) instead of dead-ending; 403 is explained without touching credentials. - Diagnostic no longer marks caps done when the manifest 401s. - Settings → User shows "Session expired" / load errors instead of "…". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
4 of 8 tasks
Contributor
Author
|
Cross-ref: #71 fixes the same failure, a TV client not recovering once the server rejects its session (401), on tv-native (Apple TV / Android TV). The two PRs are independently scoped and can be reviewed and merged separately; neither depends on the other. This one stays a draft until it's been validated on a physical Roku. |
This branch was previously deployed
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.
What & why
Once the Roku client's stored bearer token stops being honoured (sessions expire after 30 days unused, or get revoked), the client can't be used again without reinstalling:
/api/v1request returns 401. The guide shows "Couldn't load the guide. Check your connection and try again.", which treats an auth failure as a network one and offers no retry.The second bug is the real trap.
GuideSidebar.init()only calledrefresh(). Its item list (m.items) was built only byrebuild(), which runs on apackagesorlenschange.lensstarts at"all", and the Guide only ever sets it to"all"again, which doesn't fireonChange. Sorebuild()ran only if/api/v1/packagessucceeded. When that request 401s (or the server is offline),m.itemsstays empty andonActivate()drops every OK (sel >= m.items.count()). The circles still render and the focus ring still moves (itemCountdefaults to 3), so the sidebar looks fine but does nothing. The guide itself never checked for 401 either, unlike tv-web (guide-screen.tsxforces sign-out on a guide 401).This change:
init()(rebuild()), so Guide, Settings and Account work whether or not packages load.Api.errorKind(status)classifies failures asnetwork(no HTTP status: unreachable, DNS, TLS, timeout),auth(401),forbidden(403),server(5xx) orclient. Every rejection now carrieskind.Api_onResponsebumpsm.global.authRejectedon a definitive invalid-session 401. That means a bearer-carrying/api/v1/*request, rejected by the*middleware inapps/server/src/rest.ts, for the current token. The sign-in endpoints (/api/tv/auth/*,/api/auth/device/*), which 401 for a wrong password or pending code, are excluded, and so are stale requests carrying a token that has since been replaced.MainScene.onAuthRejectedclears only the token, keeps the server URL, tears down the player and routes to Login with a "Your session expired" notice. It's idempotent: the token is gone after the first signal, so the parallel 401s from favorites, packages and heartbeat are no-ops and can't loop. A network failure never reaches it, so a flaky connection can't sign anyone out.get-sessionreturns 200 + null for a dead token) or a load error instead of a permanent "…". Sign out was always local and still works.No server or API changes. The fix uses the existing 401/403 contract and the existing Login / device-pairing flows.
Area
Testing
These are three separate claims. Only the first two have been established.
pnpm --filter tv-roku build(bsc + bslint) exits 0. The only diagnostics are the twoBSLINT1005warnings that already exist onmain(ChannelRow.bs,Guide.bs).bsfmtmakes the same number of changes to every touched.bsfile before and after this PR, so the PR adds no formatting violations.Api_errorKind/Api_isSessionRejectionunder a BrightScript interpreter (brs-nodeCLI, out of tree): 18/18 cases pass. They cover status 0 / negative curl codes → network; 401 / 403 / 5xx / 4xx; bearer vs no bearer;/api/tv/auth/passwordand/api/auth/device/token401s excluded; a stale token after re-login; already signed out. The harness exits non-zero on any failure, and I confirmed it goes red with a deliberately broken case. tv-roku has no in-repo test harness, so this is not committed. Adding Rooibos or similar is out of scope here.The interpreter run doesn't count as evidence for any of those.
I'm opening this as a draft until an on-device sideload run covers item 3.
Checklist
pnpm --filter tv-roku build).envvalues committed🤖 Generated with Claude Code