Skip to content

Bad error handling in decode_cf_variables can lead to TypeError #10873

@jonaslb

Description

@jonaslb

What is your issue?

We're using a provider library for some data loading based on Zarr stores served over HTTP.
Unfortunately, they have issues sometimes, resulting in error 500s being raised. That's on them and not Xarray of course, but it also looks like Xarray has some bad error handling that prevents us from "properly" catching this error at a higher level.

I did try to do a minimal reproducer by just raising inside a dask-delayed chunk, but it was not sufficient, so it seems the error is only triggered through certain codepaths (and in any case, the culprit below is very clear on what the problem is).

See this traceback snippet:

... (snipped most of it) ...
    |   File "/app/.venv/lib/python3.13/site-packages/provider_library/_utils/dataset.py", line 88, in _open_dataset
    |     dataset = xr.open_dataset(path, **kwargs)
    |   File "/app/.venv/lib/python3.13/site-packages/xarray/backends/api.py", line 596, in open_dataset
    |     backend_ds = backend.open_dataset(
    |         filename_or_obj,
    |     ...<2 lines>...
    |         **kwargs,
    |     )
    |   File "/app/.venv/lib/python3.13/site-packages/xarray/backends/zarr.py", line 1677, in open_dataset
    |     ds = store_entrypoint.open_dataset(
    |         store,
    |     ...<6 lines>...
    |         decode_timedelta=decode_timedelta,
    |     )
    |   File "/app/.venv/lib/python3.13/site-packages/xarray/backends/store.py", line 45, in open_dataset
    |     vars, attrs, coord_names = conventions.decode_cf_variables(
    |                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    |         vars,
    |         ^^^^^
    |     ...<7 lines>...
    |         decode_timedelta=decode_timedelta,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     )
    |     ^
    |   File "/app/.venv/lib/python3.13/site-packages/xarray/conventions.py", line 425, in decode_cf_variables
    |     raise type(e)(f"Failed to decode variable {k!r}: {e}") from e
    |           ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | TypeError: ClientResponseError.__init__() missing 1 required positional argument: 'history'
    +------------------------------------

The expression type(e)(f"Failed to decode variable {k!r}: {e}") is very clearly just wrong. The constructor of an unknown type cannot be called like that, because the call signature is unknown. It is necessary (and best practice) to use a known and/or own exception type.

Just for additional info, the underlying exception type is a aiohttp.client_exceptions.ClientResponseError.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions