Skip to content

fix(menu): readable API errors, no false Offline, full long-break range - #17

Merged
tarakanof merged 3 commits into
mainfrom
fix/pomodoro-error-surfacing
Jun 10, 2026
Merged

tarakanof merged 3 commits into
mainfrom
fix/pomodoro-error-surfacing

Conversation

@tarakanof

Copy link
Copy Markdown
Owner

What

Three menu-app fixes that fell out of debugging "Save failed: The operation couldn't be completed. (EmberKit.APIError error 0.)" on the Pomodoro tab:

  1. Readable API errors — APIError now conforms to LocalizedError. The old message was the raw NSError bridge; the actual cause (HTTP 404 pomodoro feature is not enabled from a pre-v0.5.0 server) was invisible. Error text now shows the server's {\"error\":…} field when present, plus a clearer Pomodoro-tab load-failure caption.
  2. No false Offline — AppModel.refresh() awaited /state + pomodoro state/stats in one try, so the 404s those endpoints return while Pomodoro is disabled blanked the dashboard and showed Offline despite a healthy server. Connectedness is now decided by /state alone; pomodoro fields degrade to nil.
  3. Long-break stepper 1–180 — UI capped at 120 while validatePomodoro allows 180, making 121–180 (set via config.json) sticky in the UI.

Why the original error happened

The running container is still v0.4.0 (6ad0339), which gates PUT /v1/pomodoro/config behind the enabled flag — the 0.5.0 app's Enable toggle can't work against it. Fix is a redeploy to dtarakanov/ember:0.5.0 (image already published); these changes make the failure self-explanatory if it ever recurs.

Testing

  • New tests: APIErrorDescriptionTests (5 cases) + refreshStaysConnectedWhenPomodoroDisabled.
  • swift test: 78/78 pass. App target builds (xcodebuild -scheme Ember).

…r N.'

APIError lacked LocalizedError, so every settings footer rendered the
NSError bridge ('The operation couldn't be completed. (EmberKit.APIError
error 0.)') instead of the server's message. Enabling Pomodoro against a
pre-v0.5.0 server failed with exactly that string, hiding the actual
cause ('pomodoro feature is not enabled', HTTP 404). Map each case to
readable text, extract the server's {"error":…} field when present, and
show the underlying error in the Pomodoro tab's load-failure caption.
AppModel.refresh() awaited /state and both pomodoro endpoints in one
try, so the 404 those endpoints return while the feature is disabled
marked the whole app disconnected and blanked the dashboard even though
/state was healthy. Only the /state fetch now decides connectedness;
pomodoro state/stats degrade to nil on their own.
validatePomodoro accepts long_break_minutes up to 180 but the stepper
capped input at 120, making 121–180 (reachable via config.json) sticky:
any other edit couldn't be saved without first lowering the value.
@tarakanof
tarakanof merged commit 613cabb into main Jun 10, 2026
1 check passed
@tarakanof
tarakanof deleted the fix/pomodoro-error-surfacing branch June 10, 2026 17:50
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