Follow-up to #2286 (COG readiness).
Production-ready means predictable failure modes. Right now several unsupported to_geotiff(..., cog=True) input combinations may produce raw tracebacks from deep in the writer (or worse, succeed and produce a non-COG file). This issue pins each one to a typed exception with a remediation hint, and adds tests that lock the exception type and message in.
Required changes
New test file
xrspatial/geotiff/tests/test_cog_invalid_input_errors_2286.py.
For each row below, assert to_geotiff(arr, dst, cog=True, ...) raises a specific exception type with a message that names the violated constraint and tells the user what to do:
| Input |
Expected exception |
Required message content |
Experimental codec (e.g. compression='lerc') without allow_experimental_codecs=True |
ValueError (or whatever the writer raises today — pin it) |
Names the codec; tells user to set allow_experimental_codecs=True; mentions stability tier |
Internal-only JPEG (e.g. compression='jpeg') without allow_internal_only_jpeg=True |
(current writer behavior — pin it) |
Names the codec; mentions allow_internal_only_jpeg opt-in |
| Rotated transform on input DataArray |
(current writer behavior — pin it) |
Names the rotated transform; mentions the rotated-CRS opt-in path |
File-like / BytesIO destination with cog=True |
(current writer behavior — pin it) |
States that COG writes require a real path |
CuPy / GPU-backed array with cog=True |
(current writer behavior — pin it) |
States GPU COG is not in the stable contract |
| Object-dtype DataArray |
(current writer behavior — pin it) |
Names the dtype; lists supported dtypes |
Conflicting crs= and array CRS |
already covered by #1929/#1987 — confirm message still actionable, don't duplicate |
|
For each row:
- If the writer already raises a sensible typed exception with an actionable message, the test just pins it (no production change).
- If the writer raises a deep traceback (
AttributeError, KeyError, struct format error, etc.) or silently produces a non-COG, add minimal validation at the public entry to convert it to a typed exception with a clear message.
Production code (minimal)
If any row needs a validation hook, add it in xrspatial/geotiff/_writer.py (or _attrs.py if it's a contract check) near the existing input-validation block. Reuse the existing exception types where possible; do not introduce a new exception class unless none of the existing ones fits.
Out of scope
- Promoting tiers (tracked separately).
- Documentation updates (tracked separately).
- Reader-side validation.
- Changing semantics of any path that currently succeeds.
Acceptance
Follow-up to #2286 (COG readiness).
Production-ready means predictable failure modes. Right now several unsupported
to_geotiff(..., cog=True)input combinations may produce raw tracebacks from deep in the writer (or worse, succeed and produce a non-COG file). This issue pins each one to a typed exception with a remediation hint, and adds tests that lock the exception type and message in.Required changes
New test file
xrspatial/geotiff/tests/test_cog_invalid_input_errors_2286.py.For each row below, assert
to_geotiff(arr, dst, cog=True, ...)raises a specific exception type with a message that names the violated constraint and tells the user what to do:compression='lerc') withoutallow_experimental_codecs=TrueValueError(or whatever the writer raises today — pin it)allow_experimental_codecs=True; mentions stability tiercompression='jpeg') withoutallow_internal_only_jpeg=Trueallow_internal_only_jpegopt-inBytesIOdestination withcog=Truecog=Truecrs=and array CRSFor each row:
AttributeError,KeyError, struct format error, etc.) or silently produces a non-COG, add minimal validation at the public entry to convert it to a typed exception with a clear message.Production code (minimal)
If any row needs a validation hook, add it in
xrspatial/geotiff/_writer.py(or_attrs.pyif it's a contract check) near the existing input-validation block. Reuse the existing exception types where possible; do not introduce a new exception class unless none of the existing ones fits.Out of scope
Acceptance