Skip to content

Migrate screen commands to v4.1 API and improve error messages#294

Open
514sid wants to merge 5 commits into
Screenly:masterfrom
514sid:feature/v4.1-screens
Open

Migrate screen commands to v4.1 API and improve error messages#294
514sid wants to merge 5 commits into
Screenly:masterfrom
514sid:feature/v4.1-screens

Conversation

@514sid

@514sid 514sid commented Jun 6, 2026

Copy link
Copy Markdown
Member

Moves all screen operations from v3/v4 to the v4.1 API and improves how API errors are reported to the user.

Changes

Screen API migration (v3/v4 → v4.1)

  • screen list and screen get — updated from v4/screens to v4.1/screens
  • screen add — replaced the manual v3 POST (which returned a single object and required wrapping it in an array) with commands::post against v4.1/screens, which returns an array natively
  • screen delete — replaced DELETE /v3/screens/<id>/ with PostgREST filter syntax DELETE /v4.1/screens?id=eq.<id>, consistent with how other v4.1 endpoints work
  • MCP screen tools updated to match

Error message improvements

  • Added ApiError(String) variant to CommandError for cases where the API returns a human-readable message in the response body
  • commands::post now parses the error field from non-2xx JSON responses and returns ApiError instead of a bare status code — so screen add with a wrong pin now shows "Invalid pin" instead of "unexpected response status: 400"
  • Renamed WrongResponseStatus message from "unknown error: {N}" to "unexpected response status: {N}" for clarity
  • The catch-all error handler now uses Display formatting instead of Debug, so users see the #[error("...")] message rather than the internal Rust variant name

514sid added 3 commits June 6, 2026 13:28
Add ApiError variant to CommandError and parse the 'error' field from
JSON response bodies in commands::post, so callers see the API's own
message instead of a raw status code or debug-formatted variant name.
All screen operations now use v4.1 endpoints:
- list/get use v4.1/screens (was v4/)
- add uses commands::post with v4.1/screens (was manual v3 POST with
  array wrapping; v4.1 returns arrays natively)
- delete uses PostgREST filter syntax v4.1/screens?id=eq.<id>
  (was v3/screens/<id>/)

Adds a test for the invalid pin error path.

@sergey-borovkov sergey-borovkov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — Migrate screen commands to v4.1 API and improve error messages

Overview

Switches screen list/get/add/delete (plus MCP screen tools) from v3/v4 to v4.1 endpoints, and surfaces server-supplied error messages from commands::post via a new CommandError::ApiError(String) variant. Net +49/−36 across 5 files. Tests are updated and a new test covers the ApiError path.

Strengths

  • Endpoint migration is consistent across CLI, MCP tools, and tests — no stragglers on the screen path.
  • screen add now reuses commands::post instead of an open-coded reqwest call, eliminating duplicated POST plumbing and the v3 array-wrapping hack.
  • commands::post switches from response.text()? to response.text().unwrap_or_default() on the error path. This is an actual bug fix: previously, if reading the error body failed, the request error masked the original status error.
  • The ApiError test (test_add_screen_wrong_pin_should_fail_with_api_error_message) is tight and verifies the user-visible string, not just the variant.

Issues / Suggestions

1. ApiError parsing is only in post (src/commands/mod.rs:180–189)
get, delete, and patch all still return WrongResponseStatus(N) on non-2xx — so a wrong-pin equivalent through a different verb (e.g. a future screen update via patch, or a v4.1 delete that 400s) will still show unexpected response status: 400. If the goal is users see the API's error message, consider lifting the JSON-error extraction into a small helper and calling it from all four functions. Even better: also fall back to message/detail keys, since not every API surface uses error.

2. Inconsistent Debug → Display change (src/cli.rs:512)
Only the one catch-all site changed from {e:?} to {e}. The other ~14 error!(\"Error occurred: {e:?}\") sites in cli.rs (lines 582, 674, 815, 850, 861, 876, 887, 901, 1028, …) still use Debug. If the rationale is users shouldn't see Rust variant names, this should be applied uniformly — otherwise behaviour depends on which command path you hit. Either sweep them all or add a comment explaining why this one site differs.

3. Subtle behaviour change in screen add acceptance (src/commands/screen.rs:42)
The old open-coded path required exactly 201 CREATED. commands::post accepts 201, 200, or 204. If v4.1 ever returns 200 for a duplicate-or-similar case, screen add will now silently succeed where it used to error. Likely fine for PostgREST conventions (returns 201 for inserts), but worth confirming against the v4.1 spec.

4. Delete test only asserts URL shape (src/commands/screen.rs:160–166)
The new delete test verifies the v4.1 path/query syntax but doesn't add an assert! against the mock or assert success of the result. Minor — existing pattern probably covers this elsewhere — but a delete_mock.assert(); assert!(result.is_ok()); would lock the behaviour.

Risk Assessment

  • Backwards compatibility: v3 screen add returned a single object; v4.1 returns an array. The PR handles this correctly and the public Screens wrapper hides the shape from callers. Anyone scripting against --json output would see no change (was already wrapped in an array).
  • Error format change: Users who grep CLI stderr for unknown error: 400 will break. Low risk but worth a note in release notes.
  • Security: No new auth surface or input-validation concerns.

Verdict

Solid migration with a real UX improvement. Main thing I'd push back on is the inconsistency: error-message extraction lives only in post, and the Debug→Display switch hit only 1 of 15 sites. Either of those is approvable on its own; together they make the error message UX half of the PR feel half-done. Worth either expanding the scope or splitting into a follow-up issue.

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.

2 participants