Skip to content

fix(plex): bound request timeout and surface watch-history errors#2773

Merged
enoch85 merged 2 commits into
developmentfrom
fix/plex-request-timeout
Apr 26, 2026
Merged

fix(plex): bound request timeout and surface watch-history errors#2773
enoch85 merged 2 commits into
developmentfrom
fix/plex-request-timeout

Conversation

@enoch85

@enoch85 enoch85 commented Apr 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds PLEX_REQUEST_TIMEOUT_MS (30s) to the runtime PlexApi client. Previously had no socket timeout, so a wedged Plex request could hang the rule executor forever (#2771).
  • Aligns plexApi.getWatchHistory with the Jellyfin adapter's contract: errors propagate so callers can distinguish a real outage from a confirmed empty history. Removes silent .catch(() => null) swallowers in seenBy, sw_allEpisodesSeenBy, and collection_siblings_lastViewedAt that previously turned transient lookup failures into "viewed by no one" — leaking into NOT_EXISTS checks and missing-value diagnostics.

Refs #2771

@enoch85

enoch85 commented Apr 26, 2026

Copy link
Copy Markdown
Collaborator Author

/release-pr

The runtime PlexApi client had no socket timeout, so a wedged Plex
request could hang the rule executor forever. Add PLEX_REQUEST_TIMEOUT_MS
(30s) to bound it.

Also align plexApi.getWatchHistory with the Jellyfin adapter's contract:
errors propagate so callers can distinguish a real outage from a
confirmed empty history (matches the design documented for the rules
layer's NOT_EXISTS / missing-value handling). Removes silent
.catch(() => null) swallowers in seenBy, sw_allEpisodesSeenBy and
collection_siblings_lastViewedAt that previously turned transient
lookup failures into "viewed by no one".

Refs #2771
@enoch85 enoch85 force-pushed the fix/plex-request-timeout branch from 07f5265 to 6e39196 Compare April 26, 2026 02:16
@github-actions

Copy link
Copy Markdown
Contributor

Released to maintainerr/maintainerr:pr-2773 🚀

@enoch85 enoch85 merged commit 90a4eb1 into development Apr 26, 2026
12 checks passed
@enoch85 enoch85 deleted the fix/plex-request-timeout branch April 26, 2026 13:55
maintainerr-automation Bot added a commit that referenced this pull request Apr 27, 2026
* fix(plex): bound request timeout and surface watch-history errors (#2773)

The runtime PlexApi client had no socket timeout, so a wedged Plex
request could hang the rule executor forever. Add PLEX_REQUEST_TIMEOUT_MS
(30s) to bound it.

Also align plexApi.getWatchHistory with the Jellyfin adapter's contract:
errors propagate so callers can distinguish a real outage from a
confirmed empty history (matches the design documented for the rules
layer's NOT_EXISTS / missing-value handling). Removes silent
.catch(() => null) swallowers in seenBy, sw_allEpisodesSeenBy and
collection_siblings_lastViewedAt that previously turned transient
lookup failures into "viewed by no one".

Refs #2771

* fix(overlays): preset edit, cron discoverability, tab gating (#2775)

* fix(plex): bound request timeout and surface watch-history errors

The runtime PlexApi client had no socket timeout, so a wedged Plex
request could hang the rule executor forever. Add PLEX_REQUEST_TIMEOUT_MS
(30s) to bound it.

Also align plexApi.getWatchHistory with the Jellyfin adapter's contract:
errors propagate so callers can distinguish a real outage from a
confirmed empty history (matches the design documented for the rules
layer's NOT_EXISTS / missing-value handling). Removes silent
.catch(() => null) swallowers in seenBy, sw_allEpisodesSeenBy and
collection_siblings_lastViewedAt that previously turned transient
lookup failures into "viewed by no one".

Refs #2771

* fix(overlays): resolve preset edit, cron discoverability, and tab gating issues

- Fix #2768: preset edit now opens the editor with a copy-on-save flow
  (info description, "Save as copy" button, name modal) and remounts on
  id change so switching to /new from a preset URL no longer leaks state.
- Add post-save modal prompting for a cron schedule when overlays are
  enabled with no schedule set, with a direct link to Job Settings.
- Gate template tabs and Run Now / Reset on persisted overlay-enabled
  state; redirect direct nav to /overlays/templates when disabled.
- Add Docs button on Overlay Settings linking to docs.maintainerr.info/overlays.
- Add useOverlaySettings query + useUpdateOverlaySettings mutation
  mirroring useSettings/usePatchSettings, so the wrapper re-evaluates
  gating after save via cache propagation.
- Extract BrandLink shared component for inline branded body-text links;
  swap manual styling in Metadata, Jobs, AddModal, Calendar, StorageMetrics.
- Replace crontab.org with crontab.guru and dedupe per-row cron links
  into a single link in the Job Settings page description.
- Suppress success alert on copy-on-save navigation (the URL change is
  the confirmation; the alert flashed for one frame and disappeared).
- Sync workspace MCP config (.mcp.json + .vscode/mcp.json) to use
  --output-dir .playwright-mcp; document screenshot path requirement.

* fix(ui): unblock tsc + fix the type errors it was hiding (#2776)

apps/ui/tsconfig.json had ignoreDeprecations: "6.0", which is invalid
for TypeScript 5.x and caused tsc to bail before type-checking. CI
exited 0 without scanning anything, so eight pre-existing type errors
went unreported.

- Remove the invalid ignoreDeprecations option (no deprecated options
  remain in the tsconfig that need silencing).
- Drop unused imports in CollectionInfo (DocumentTextIcon,
  CollectionLogDto, isMetaActionedByRule).
- Add the missing MediaItem fields (guid, addedAt, providerIds,
  mediaSources, library) to the CollectionMediaPage test fixture.
- Update the UseQueryResult / QueryClient mock casts in two specs to
  use the project's existing `as unknown as ...` double-cast pattern
  (matches 12 other specs).

* ci(fider): tighten triage script and surface pre-existing matches in re-eval

Re-evaluate workflow can now catch "feature already exists, user didn't know"
cases that the daily triage's PR-prefix gate misses (e.g. foundational
date-rule support that predates the feat:/fix: convention).

- Lift sleep + the entire model-call layer (throttle, per-run budget,
  retry-with-backoff, retry-after handling, header logging) from
  fider-triage.mjs into a createModelCaller factory in fider-shared.mjs.
- Replace the wrong "Copilot Free 15 RPM / 150 RPD" comment with the
  observed runner-token budget (1000 RPM / 1M TPM, no exposed daily cap)
  from a real re-eval run; pace 1 call/sec with an 800-call sanity ceiling.
- BudgetExhaustedError now propagates through triagePost catches so main()
  aborts cleanly with a deferred-posts log instead of burning iterations
  into the consecutive-failure abort.
- Drop the feat:/fix: PR-title prefix gate on the pre-existing path when
  forceReeval=true; daily run still enforces it for precision.
- Re-eval workflow now sets CHECK_PRE_EXISTING=true so the relaxed path
  actually runs.
- MAX_POSTS_PER_RUN 25 -> 100; consolidate the three judge*WithModel and
  build*Comment functions; collapse filterCandidates +
  filterPreExistingCandidates into one parametric filterPRs.

Net: triage script 844 -> 649 lines (-23%), shared +117 for the lifted
infra; behaviour preserved end-to-end (comment markers byte-identical,
tag slugs unchanged, quote-validation rejection paths preserved).

* ci(fider): @-mention OP and nudge to split bundled requests in possibly-pre-existing comment

Both pre-existing flags from the latest re-eval run were partial matches
caused by multi-ask FRs: the bot quoted a PR that delivered one bullet
of a wishlist and tagged the post pre-existing. The new footer addresses
the OP directly via @-mention (already returned on every post by
/api/v1/posts) and asks them to split bundled requests so each can be
triaged independently. The long maintainer-facing "lower confidence than
possibly-completed" preamble that the OP didn't need is gone.

Comment-marker idempotency means existing pre-existing comments will be
edited (not duplicated) to the new text on the next re-eval run.

* Fix overlay SSE EPIPE handling (#2781)

* Fix overlay SSE EPIPE handling

* refactor(overlays,sse): tighten SSE writer API and overlay revert semantics

- Expose send() on SseStreamClient instead of the raw RxJS Subject
- Restore clearAllStates() in resetAllOverlays so reset is a hard wipe
- Drop no-op axios try/catch in plex-api uploadPoster
- Use plain warn() + debug(error) per logging convention
- RevertItemResult as discriminated string union

---------

Co-authored-by: enoch85 <mailto@danielhansson.nu>

---------

Co-authored-by: enoch85 <mailto@danielhansson.nu>
Co-authored-by: Kristian Matthews-Kennington <kristian@matthews-kennington.com>
@enoch85 enoch85 added this to the 3.9.0 milestone Apr 28, 2026 — with GitHub Codespaces
@maintainerr-automation

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.9.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant