Raise explicit errors for unsupported capabilities - #120
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR formalizes “unsupported optional endpoint” handling by introducing a dedicated public exception type and updating client helpers to raise it (instead of returning ambiguous None) when the Duco device explicitly reports an endpoint as unsupported (HTTP 400 with Code: 3).
Changes:
- Added
DucoUnsupportedCapabilityErroras aDucoResponseErrorsubclass and exported it publicly. - Updated optional-capability helpers to raise the new exception for the “unsupported endpoint” response pattern, while keeping payload omissions represented via
None/optional fields. - Updated tests and documentation to reflect the new contract (with one remaining doc inconsistency called out in comments).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tests/test_exceptions.py |
Adds coverage asserting the new exception preserves response context. |
tests/test_client.py |
Updates client behavior tests to expect DucoUnsupportedCapabilityError and asserts non-optional return typing for ventilation temperatures. |
src/duco_connectivity/exceptions.py |
Introduces DucoUnsupportedCapabilityError (with a recommended message improvement). |
src/duco_connectivity/client.py |
Raises DucoUnsupportedCapabilityError on the specific unsupported-endpoint response pattern for selected helpers. |
src/duco_connectivity/__init__.py |
Exposes the new exception in the public API exports. |
README.md |
Documents the new error-handling contract for unsupported optional endpoints. |
docs/api-reference.md |
Updates the signature and export list, but still contains an outdated note about returning None (commented). |
Comments suppressed due to low confidence (1)
docs/api-reference.md:193
- The API reference still states this helper “Returns
Nonewhen the box reports the optional endpoint as unavailable”, but the implementation/tests now raise DucoUnsupportedCapabilityError for that case. The note should match the new public contract to avoid misleading consumers.
- `async_get_ventilation_temperature_info() -> VentilationTemperatureInfo`
- Endpoint: `GET /info?module=Ventilation`
- Surface: wrapper
- Summary: Return ventilation temperatures when the box exposes them, in Celsius.
- Note: Converts the raw Duco decicelsius ventilation sensor values to Celsius.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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
Raises
DucoUnsupportedCapabilityErrorwhen a Duco box explicitly reports an optional endpoint as unsupported with400andCode: 3.Successful ventilation-temperature reads now always return
VentilationTemperatureInfo. Payload-level omissions remain represented as optional fields orNonewhere appropriate, while unsupported endpoints have an explicit public error contract.Why
This keeps unsupported API capabilities distinct from valid empty responses and lets downstream consumers disable unavailable capability probes without relying on ambiguous optional return values.
Validation
pytestruff check src testsruff format --check src testsmypy srcbandit -r src -llpip-audit --desc on