Capture un-loadable NetCDF objects instead of discarding/crashing #6317
Labels
Dragon 🐉
https://github.com/orgs/SciTools/projects/19?pane=info
Experience: High
Feature: NetCDF + CF-conventions
Release: Minor
Status: Work in Progress
Type: Enhancement
Milestone
Uh oh!
There was an error while loading. Please reload this page.
Closes #5165
User story
Why this is hard
There are many ways Iris crashes when it encounters bad CF. It is tempting to think of these crashes as deliberate - with easy-to-modify code blocks for each rule - and there are a few of these, but Iris is not a CF-checker. Instead we have used CF to make assumptions so that the code can be simpler/smaller; barely any of the crashes are raised from dedicated lines, and they are often hard to predict.
Any 'fix' must therefore be a form of generic error handling, which cannot have knowledge of what precisely might go wrong.
The architecture
iris.LOAD_PROBLEMS
- a global object where Iris can capture objects that could not be loaded, and the stack trace error that was raised.build_raw_cube()
- a routine that will represent anyCFVariable
as a very basicCube
, with as little interpretation as possible.Cube
being loaded._add_or_capture()
:build_raw_cube()
and store iniris.LOAD_PROBLEMS
.Cube
? Store iniris.LOAD_PROBLEMS
.iris.LOAD_PROBLEMS
.Cube
s - output byraw_cube_from_cf_var()
- into other objects e.g.DimCoord
s? Documentation at the very least.Note that I have checked
cf.py
and believe it can remain unchanged. This has a defensive philosophy already, which involves checking if variables can be interpreted as different types, and the remainder are all represented asCfDataVariables
, so we already have an existing fallback in place. Anything here that is not formatted correctly just shows up as extraCube
(s) in the loadedCubeList
.More specifics on implementation
For reference when writing #6318 and #6319
Iris:__init__.py
LOAD_PROBLEMS
object{"file/path/1": [(problem_object_1, error_or_stacktrace), (problem_object_1, error_or_stacktrace)]}
helpers.py
:Introduce a new function -:_add_or_capture()
- thatbuild_
routine (passed as an argument) in atry
-except
build_raw_cube()
.DimCoord
) to aCube
(passed as an argument) in atry
-except
iris.LOAD_PROBLEMS
instead.Create thebuild_raw_cube
functionbuild_
routines. We already have many, but even getting hold of standard names etcetera should be separated in this way.build_
routines to only perform the building - returning the built object rather than adding it to theCube
._build...
- and call them frombuild_and_add...
routines, which prepare the necessary arguments for_add_or_capture()
. Here are examples that have already been completed:build_and_add_dimension_coordinate
build_and_add_names
actions.py
:action_
routines have success criteria and failure information. These should be refactored so that a failure falls back tobuild_raw_cube()
. The failure reason (already being recorded) should be captured iniris.LOAD_PROBLEMS
. See Tolerant handling ofstandard_name
and dimension coordinate loading #6338 for how this was done with dimension coordinatesaction_
routines should be refactored to call the newbuild_and_add
routines.The text was updated successfully, but these errors were encountered: