Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a structured custom-exception hierarchy for physics-method execution, updates data-connection getters to support required=True (all-NaN detection) and raise data-specific errors, and adjusts runners/physics methods to use and handle these new exceptions more consistently.
Changes:
- Added
CustomErrorbase class withDataError/CalculationErrorbranches and specific subclasses (e.g.,FetchDataError,NanDataError,MismatchCalculationError). - Updated
XarrayDataConnectionandMDSConnectiongetters to acceptrequiredand raiseFetchDataError/NanDataErrorwhere applicable. - Updated the physics-method runner to downgrade all
CustomErrors to warnings and migrated several call sites to the new exception types.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| disruption_py/machine/mast/util.py | Uses MismatchCalculationError for interpolation input-length mismatch. |
| disruption_py/machine/mast/physics.py | Uses MismatchCalculationError for density timebase length mismatch. |
| disruption_py/machine/d3d/physics.py | Raises FetchDataError for an invalid data_source case. |
| disruption_py/machine/cmod/physics.py | Adopts FetchDataError / MismatchCalculationError in a few data/mismatch scenarios and improves one error message. |
| disruption_py/inout/xr.py | Adds required checks and raises FetchDataError/NanDataError instead of returning sentinels. |
| disruption_py/inout/mds.py | Adds required checks and raises NanDataError for all-NaN data. |
| disruption_py/inout/base.py | Extends the DataConnection interface with required: bool = False. |
| disruption_py/core/physics_method/runner.py | Treats any CustomError as warning-level (vs. only CalculationError previously). |
| disruption_py/core/physics_method/errors.py | Defines the new exception hierarchy and subclasses. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
|
|
||
| class NanDataError(DataError): | ||
| """ | ||
| NaN data error. | ||
| """ | ||
|
|
||
|
|
||
| class MismatchCalculationError(CalculationError): | ||
| """ | ||
| Mismatch calculation error. | ||
| """ |
There was a problem hiding this comment.
The new exception classes don’t provide structured context or helpful default messages. As used elsewhere (e.g., FetchDataError(path) / NanDataError(path)), str(e) becomes only the raw argument, which makes warnings harder to understand. Consider adding __init__ implementations that accept relevant fields (e.g., path, reason, expected/actual) and build a clear message, and optionally store those fields as attributes for downstream handling/logging.
| class NanDataError(DataError): | |
| """ | |
| NaN data error. | |
| """ | |
| class MismatchCalculationError(CalculationError): | |
| """ | |
| Mismatch calculation error. | |
| """ | |
| def __init__(self, path, reason=None, message=None): | |
| self.path = path | |
| self.reason = reason | |
| if message is None: | |
| message = f"Failed to fetch data for path {path!r}" | |
| if reason is not None: | |
| message = f"{message}: {reason}" | |
| super().__init__(message) | |
| class NanDataError(DataError): | |
| """ | |
| NaN data error. | |
| """ | |
| def __init__(self, path, reason=None, message=None): | |
| self.path = path | |
| self.reason = reason | |
| if message is None: | |
| message = f"NaN data encountered for path {path!r}" | |
| if reason is not None: | |
| message = f"{message}: {reason}" | |
| super().__init__(message) | |
| class MismatchCalculationError(CalculationError): | |
| """ | |
| Mismatch calculation error. | |
| """ | |
| def __init__(self, expected=None, actual=None, reason=None, message=None): | |
| self.expected = expected | |
| self.actual = actual | |
| self.reason = reason | |
| if message is None: | |
| if expected is not None and actual is not None: | |
| message = ( | |
| f"Calculation mismatch: expected {expected!r}, got {actual!r}" | |
| ) | |
| elif reason is not None: | |
| message = f"Calculation mismatch: {reason}" | |
| else: | |
| message = "Calculation mismatch" | |
| super().__init__(message) |
CustomError:DataErrorclass:FetchDataErrorandNanDataError,CalculationErrorclass:MismatchCalculationError,runner.pydowngrade allCustomErrorsto warnings,xr.pyraiseFetchDataErrorsrather than catchingKeyErrors,required=Trueargument to all data getters to check for all-NaNs arrays,