fix(api): handle GraphQL partial-success responses cleanly (CRY-61) - #150
Merged
Conversation
Linear returns HTTP 200 with both "data" and "errors" when an entity is
not found. Previously Api.handle_response/1 matched "errors" first and
returned {:error, {:graphql_errors, ...}}, which fell through to the
opaque "What the heck is this?" catch-all in CLI.handle_error/3.
Fix by matching "data" before "errors" in handle_response/1: a response
with both keys is a partial-success — the query ran, some fields are
nil. Callers already handle nil fields (fetch_one/1's {:not_found, id}
clause), so they now receive {:ok, data} and produce a clean exit-66
message instead of the crash-style fallback.
Add a safety-net handle_error/3 clause for graphql_errors that do reach
cli.ex (errors-only responses, no "data" key) — prints the API's own
error message instead of "What the heck is this?".
Closes CRY-61.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bougyman
force-pushed
the
CRY-61-clean-graphql-not-found-errors
branch
from
August 18, 2026 23:57
d9f4e90 to
959c975
Compare
bougyman
pushed a commit
that referenced
this pull request
Aug 19, 2026
🤖 I have created a release *beep* *boop* --- ## [1.15.0](v1.14.0...v1.15.0) (2026-08-19) ### Features * **issue:** add --status/-s to assign and take ([#151](#151)) ([537f54b](537f54b)) ### Bug Fixes * **api:** handle GraphQL partial-success responses cleanly (CRY-61) ([#150](#150)) ([21d0363](21d0363)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Api.handle_response/1checked"errors"before"data", so Linear's entity-not-found response (HTTP 200 with both"data": {"issue": null}and"errors": [{"type": "ENTITY_NOT_FOUND"}]) returned{:error, {:graphql_errors, ...}}— bypassingfetch_one/1's existing nil-data handler and falling through to the "What the heck is this?" catch-all.handle_response/1to check"data"first. A response with both keys is a GraphQL partial-success; callers already handle nil fields (fetch_one/1's{:not_found, id}clause), so they now see{:ok, data}and produce a clean exit-66 message.handle_error/3clause for graphql errors that reachcli.exwithout being converted (errors-only responses, no"data"key) — prints the API's own error message instead of the opaque fallback.Test plan
mix test— all new tests pass, no regressions (272/278; 6 pre-existing git test failures unrelated to this change)mix compile --warnings-as-errors— cleanmix credo— no issuesApi.callwith partial-success response returns{:ok, data}(api_test.exs)Linear.issues/1with ENTITY_NOT_FOUND response normalises to{:not_found, id}(issue_test.exs)issue developwith ENTITY_NOT_FOUND exits 66 with clean message, not "WTH" (cli_test.exs)Closes CRY-61
🤖 Generated with Claude Code