fix(plex): round-2 deep-review follow-ups on the review fixes

- collections: the resync-failed-after-successful-write path now returns 422
  (honest "reconcile on next sync" detail), NOT 502. The frontend treats
  502/503/504 as gateway-unreachable and raises a sticky offline banner
  (api/core.ts RETRIABLE_GATEWAY); the app answered, so a 422 action-error
  toast is correct. Removes the false-offline regression the 502 introduced,
  and — since 422 isn't retried — the create double-write vector with it.
- tests: make the mutate-then-resync rollback assertion non-vacuous — the
  resync stub now flushes a partial local change before raising, so the test
  proves db.rollback() actually undoes it; split into a write-failed (422)
  case and a resync-failed (422 + reconcile detail + rollback) case.
- New-collection dup hint is now muted-tone with its own nameMaybeTaken copy
  (per-library uniqueness means the name may be free here) instead of the red
  authoritative nameTaken, which the still-enabled create flow contradicts.
- history: cover the navCounter post-reload collision guard (ensureNavId
  advances the counter past a higher persisted sfScroll id).
This commit is contained in:
2026-08-23 07:22:53 +02:00
parent 6af238c2ea
commit 7d2bee59a3
6 changed files with 44 additions and 20 deletions
+14 -12
View File
@@ -209,20 +209,22 @@ def _reject_duplicate_name(
def _write_or_pending_error(wrote: bool, e: Exception) -> HTTPException:
"""Map a PlexError raised inside a mutate-then-resync block to the honest status. If the mutating
call itself failed (``wrote`` False) the write never landed → 422 "Plex write failed". If the
write succeeded but the follow-up resync READ (Plex metadata/children) failed, the change IS on
the Plex server → don't claim a write failure; report 502 "sync pending" (the next full sync
reconciles the local mirror)."""
"""Map a PlexError raised inside a mutate-then-resync block to the honest message. If the mutating
call itself failed (``wrote`` False) the write never landed → "Plex write failed". If the write
succeeded but the follow-up resync READ (Plex metadata/children) failed, the change IS on the Plex
server → don't claim a write failure; say the local copy will reconcile on the next sync.
Both use 422, NOT a 5xx: the frontend treats 502/503/504 as "gateway unreachable" and raises a
sticky offline banner (see api/core.ts RETRIABLE_GATEWAY). A 422 surfaces the detail as an ordinary
action-error toast, which is what both of these are — the app answered, it didn't go unreachable."""
if wrote:
return HTTPException(
status_code=502,
detail=(
"Collection updated in Plex, but refreshing the local copy failed; "
f"it will reconcile on the next sync ({e})"
),
detail = (
"Collection updated in Plex, but refreshing the local copy failed; "
f"it will reconcile on the next sync ({e})"
)
return HTTPException(status_code=422, detail=f"Plex write failed: {e}")
else:
detail = f"Plex write failed: {e}"
return HTTPException(status_code=422, detail=detail)
class CreateCollectionIn(BaseModel):