Skip to content

Match status ranges and default in the envelope client - #165

Merged
cubahno merged 2 commits into
mainfrom
ig/fix-envelope-ranges
Oct 8, 2026
Merged

cubahno merged 2 commits into
mainfrom
ig/fix-envelope-ranges

Conversation

@cubahno

@cubahno cubahno commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

With generate.client-with-response, 4XX and 5XX both became case 400 and a single JSON400 field, typed as whichever range the spec listed last, so a 4xx body could decode into the 5XX schema. default became an empty case 500 with no field, and was dropped entirely when explicit error codes were documented. Every other status returned a generic error without decoding its body.

What changes

  • A range gets its own fields (JSON4XX, Headers5XX) and default gets JSONDefault, each typed by its own schema.
  • Matching follows OpenAPI precedence: exact codes first, then ranges, then default. With both 400 and 4XX documented, JSON400 and JSON4XX sit alongside and a 400 fills JSON400. A documented code without a body keeps its precedence too, so a bare 410 is not decoded as 4XX.
  • The returned error is nil only for a documented success. A default that is the operation's only success counts as one for 2xx statuses only.
  • A response that $refs a component response ($ref: '#/components/responses/Error') now gets a typed field. It had none, which is how most real-world specs declare 4XX and 5XX.
  • <Op>StreamWithResponse matches error ranges and an error default the same way.
  • A default whose schema is a JSON pointer into another operation's response, as bundled specs like DigitalOcean's use, gets a type of its own instead of a reference to a type that is never generated. That already broke generation when default was the only error response.
  • Fields earlier versions generated for a range or default under a stand-in code (JSON200 for 2XX, JSON400 for 4XX, Headers500 for default) stay as deprecated aliases that always equal the new field, so existing callers compile unchanged.
  • Operations without ranges or default generate the same code as before, and so do handler, classic client and MCP generation, with one rare exception: when a range response's type needs a status suffix to stay unique, the suffix is the range (...JSON4XX), so ...JSON400 always names an explicit 400.
  • For custom templates: ranges and default are in the new ResponseDefinition.StatusRanges and Default rather than Successes/Errors, and OperationDefinition.HeaderTypeName returns any response's header type name. HeaderTypeNames is unchanged.

Fixes #161

@cubahno
cubahno marked this pull request as ready for review October 8, 2026 07:31
@cubahno
cubahno merged commit 9e082d5 into main Oct 8, 2026
3 checks passed
@cubahno
cubahno deleted the ig/fix-envelope-ranges branch October 8, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

client-with-response mishandles default and 4XX/5XX error responses

1 participant