[TV] Fix search failing on unknown combined-search result types - #5745
[TV] Fix search failing on unknown combined-search result types#5745sztomek wants to merge 2 commits into
Conversation
|
Claude finished @sztomek's task in 2m 36s —— View job Code reviewThe diagnosis and the fix are both right. Two inline comments posted. Summary of everything I found: 1.
|
|
Claude finished @sztomek's task in 2m 20s —— View job Code review (re-run on ready for review)The fix is correct and I'd ship it. One correction to my earlier review, since it changes what you might do:
|
|
Claude finished @sztomek's task in 2m 1s —— View job Code review (re-run on push — "Address PR comments")The new commit picks up both of my earlier items, and the result is a tighter fix than the original. Verified against the current tree:
The core reasoning holds: Findings1. The new
|
| val title: String? = null, | ||
| val author: String? = "", | ||
| val slug: String, | ||
| val slug: String = "", |
There was a problem hiding this comment.
Good change — slug and podcastSlug are read by nobody (ImprovedSearchManagerImpl.kt:37-61 ignores both, and there are no other consumers of CombinedResult), so requiring them was pure downside.
One caveat on how far a Kotlin default actually protects you: Moshi's generated adapter uses the default only when the key is absent. If the server sends "slug": null explicitly, codegen still hits Util.unexpectedNull(...) and throws JsonDataException: Non-null value 'slug' was null at $.results[N], which aborts the whole response exactly like the old bug. String? = null covers both the absent and explicit-null cases; String = "" covers only the first. Given the motivation here is "one weird result shouldn't wipe out the search", nullable is the stronger guarantee.
Related, and the same argument as slug: url (line 29) is still non-null-required and is likewise never read by any consumer. title/podcastUuid/podcastTitle are at least consumed, though it's a bit asymmetric that PodcastResult.title is nullable-and-filtered (ImprovedSearchManagerImpl.kt:40) while EpisodeResult.title hard-fails the response.
Not blocking — the PR's stated bug is fixed either way.
|
Version |
Description
Search hard-fails whenever the
/search/combinedresponse contains a result the client doesn't recognise. The response is decoded with a MoshiPolymorphicJsonAdapterFactorykeyed ontype, registered only forpodcastandepisode. The server also returns"type":"network"results (podcast networks), and the factory throwsJsonDataException: Expected one of [podcast, episode] for key 'type' but found 'network'— which aborts decoding of the entire response, so a search that returned perfectly good podcasts and episodes surfaces as a generic error with zero results.This reproduces for common queries (e.g.
news,search) and affects both phone and TV search (both go throughImprovedSearchManager.combinedSearch). Verified live:POST /search/combinedreturns HTTP 200 with valid results, yet the app shows the error state, with this stacktrace:Fix
Add an
Unknownfallback to the polymorphic adapter (withDefaultValue(Unknown)) so any unrecognisedtype(todaynetwork, and any future type) decodes toCombinedResult.Unknowninstead of throwing.ImprovedSearchManagerImpl.combinedSearchalready usesmapNotNull, so unknown results are simply dropped and the rest of the results render normally.Testing Instructions
news) on phone or TV → results now appear instead of an error../gradlew :modules:services:servers:testDebugUnitTest --tests "*CombinedSearchResponseTest*" :modules:services:repositories:testDebugUnitTest --tests "*ImprovedSearchManagerImplTest*"— covers the adapter tolerating anetworkresult and the mapping droppingUnknown.Screenshots or Screencast
Screen_recording_20260814_175406.mp4
Screen_recording_20260814_175445.mp4
Checklist
./gradlew spotlessApply)