Skip to content

Let unwrap() accept the ApiError of another generated client - #2

Merged
svdigital-development merged 2 commits into
mainfrom
claude/unwrap-fix
Oct 1, 2026
Merged

svdigital-development merged 2 commits into
mainfrom
claude/unwrap-fix

Conversation

@svdigital-development

Copy link
Copy Markdown
Member

Summary

shellrent-internal-sdk will reuse authentication, HTTP client and error handling from this package, but its generated client has its own ApiError: with unwrap() its documented errors became UnexpectedStatus instead of ApiException.

  • unwrap(response, *, error_type=None): another generated client passes its own ApiError. With error_type=None (or this package's ApiError) the signature and the inferred types are unchanged. With another error_type, response is typed structurally, since the other client's Response is a different class.
  • ApiErrorLike, a Protocol with read-only error: int and message: str | None, exported from shellrent_sdk. ApiException.error is typed with it, so it no longer depends on this package's ApiError.
  • ApiException reads HTTP <status> when the envelope has no message.
  • CLAUDE.md: unwrap() and ApiException added to the interface used by shellrent-internal-sdk.
  • CHANGELOG.md: section [0.2.0] (new API, so a minor release).

Notes for reviewers

  • Typing change: e.error.message is now str | None instead of str, and data/meta need isinstance(e.error, ApiError). Runtime behaviour is the same, but mypy-strict code that reads those fields must narrow first.
  • mypy limit: a direct unwrap(r, error_type=OtherApiError) does not type-check when the body is an envelope too, because it also has error and message, so mypy cannot tell the two apart. The other client should define its own unwrap() that calls this one; the example is in the docstring and covered by the tests.
  • unwrap() still raises this package's UnexpectedStatus, not the other client's.

Test plan

  • New tests/unit/test_errors.py: another client's ApiError passed with error_type raises ApiException; the body is returned with the right type (checked with assert_type); ApiException without message; this package's ApiError is the default.
  • ruff format, ruff check, mypy, pytest (119 passed)
  • Same checks on Python 3.11 with --resolution lowest-direct

🤖 Generated with Claude Code

Tobia Zanarella and others added 2 commits October 1, 2026 10:35
error_type and ApiErrorLike are new API: a minor version, not a patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@svdigital-development
svdigital-development merged commit 5951010 into main Oct 1, 2026
6 checks passed
@svdigital-development
svdigital-development deleted the claude/unwrap-fix branch October 1, 2026 08:59
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