Skip to content

Improve Location validation and error handling#248

Draft
llucax wants to merge 9 commits into
frequenz-floss:v0.x.xfrom
llucax:err-location
Draft

Improve Location validation and error handling#248
llucax wants to merge 9 commits into
frequenz-floss:v0.x.xfrom
llucax:err-location

Conversation

@llucax

@llucax llucax commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Make latitude and longitude required to match the protobuf definition while keeping country_code optional even when it is required because in practice it could be missing (encoded as "").

We now also allow storing invalid values, but encoded via new types: InvalidLatitude, InvalidLongitude, and InvalidCountryCode. This way users still can't read invalid values accidentally. This allows users to inspect invalid values if they need to, instead of only reporting via logging.

Add new safe accesors for Location attributes and Microgrid.location to allow users to safely access the values without having to check for validity themselves.

Part of #239.

@llucax llucax added the cmd:skip-release-notes It is not necessary to update release notes for this PR label Jul 9, 2026
@github-actions github-actions Bot added part:docs Affects the documentation part:tests Affects the unit, integration and performance (benchmarks) tests part:grid Affects the grid protobuf definitions part:metrics Affects the metrics protobuf definitions part:microgrid Affects the microgrid protobuf definitions labels Jul 9, 2026
@llucax llucax self-assigned this Jul 9, 2026
@llucax llucax added this to the v0.4.1 milestone Jul 9, 2026
@llucax llucax force-pushed the err-location branch 2 times, most recently from cefacfc to 27f666a Compare July 9, 2026 13:39
llucax added 9 commits July 10, 2026 08:47
This exception will be the base for any exception raised when an
attribute that holds invalid data is accessed through a semantic
accessor.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Make `UnrecognizedEnumValueError` and `UnspecifiedEnumValueError`
inherit from `InvalidAttributeError`.

Also split exception tests as the file grew too much when adding the new
tests.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Add a new top-level exception `MissingFieldError`, sibling of
`UnspecifiedEnumValueError`, to signal that a semantic accessor was
called on a wrapper field that resolves to `None` because the underlying
field was not set on the wire.

The first user is the upcoming `Microgrid.get_delivery_area()` accessor
(delivery area may be `None`, `InvalidDeliveryArea`, or `DeliveryArea`),
but the pattern is expected to recur wherever an accessor unifies a
`T | ... | None` field into a plain `T` return.

Like `Unspecified/UnrecognizedEnumValueError`, it multi-inherits from
`ClientCommonError` and `ValueError` for convenience.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Add three new subclasses of `InvalidAttributeError`:

* `InvalidLatitudeError` — the raw `float` was outside `[-90, 90]`
* `InvalidLongitudeError` — the raw `float` was outside `[-180, 180]`
* `InvalidCountryCodeError` — the raw `str` was not exactly 2 characters

Each stores the offending value on `.value` (`float` for the coordinate
errors, `str` for the country code error).

These will be raised by the upcoming `Location.get_latitude()`,
`.get_longitude()` and `.get_country_code()` accessors (next commits),
where the low-level fields on `Location` may carry the raw invalid data
that came off the wire.

Also split `test_location.py` into multiple files as it will grow.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
These classes will be used to store invalid location attributes
explicitly, so they can still be inspected, but can't be used
accidentally.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Use the new invalid types for typing `Location` attributes, so invalid
values are only accepted while using the wrapper type.

This avoids accidental usage of invalid values, and accidental
construction of invalid locations, while still allowing for inspection
and construction when invalid values are explicitly requested.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Add `get_latitude()`, `get_longitude()`, `get_country_code()` and
`get_country_code_or_none()`. These accessors raise on invalid (or
sometimes missing) data.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Add `Microgrid.get_location() -> Location`, the safe counterpart of the
`Microgrid.location` field. It resolves the optional underlying field to
a concrete `Location`:

* `None` (the field was not set on the wire) → `MissingFieldError`.
* `Location` → returned unchanged.

Callers that need validated coordinates or a validated country code
should chain through the new
`Location.get_{latitude,longitude,country_code}()` accessors on the
returned instance.

Also generalize the file-local `_make_microgrid` test helper to accept
both `delivery_area` and `location` as keyword-only arguments (both
default to `None`), and update the existing `get_delivery_area()` tests
to pass `delivery_area` by keyword — no behavior change, just the same
helper covering both accessor test suites.

Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cmd:skip-release-notes It is not necessary to update release notes for this PR part:docs Affects the documentation part:grid Affects the grid protobuf definitions part:metrics Affects the metrics protobuf definitions part:microgrid Affects the microgrid protobuf definitions part:tests Affects the unit, integration and performance (benchmarks) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant