diff --git a/gufe/protocols/__init__.py b/gufe/protocols/__init__.py index fca9b580..07f7599e 100644 --- a/gufe/protocols/__init__.py +++ b/gufe/protocols/__init__.py @@ -1,5 +1,6 @@ """Defining processes for performing estimates of free energy differences""" +from.errors import ProtocolAnalysisError, ProtocolExecutionError, ProtocolValidationError, ProtocolProtocolSetupError, ProtocolUnitFailureError, MissingProtocolUnitError from .protocol import Protocol, ProtocolResult from .protocoldag import ProtocolDAG, ProtocolDAGResult, execute_DAG from .protocolunit import Context, ProtocolUnit, ProtocolUnitFailure, ProtocolUnitResult diff --git a/gufe/protocols/errors.py b/gufe/protocols/errors.py new file mode 100644 index 00000000..491cbfff --- /dev/null +++ b/gufe/protocols/errors.py @@ -0,0 +1,24 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/gufe + + +# Protocol Errors +class ProtocolValidationError(Exception): + """Error when the protocol setup or settings can not be validated.""" + +class ProtocolProtocolSetupError(Exception): + """Error when executing the setup unit of the protocol.""" + +class ProtocolExecutionError(Exception): + """Error when executing the production unit of the protocol.""" + +class ProtocolAnalysisError(Exception): + """Error when trying to perform some analyses after the protocol has been executed.""" + + +# Protocol Results Errors +class MissingProtocolUnitError(Exception): + """Error when a ProtocolDAGResult is massing a protocol unit.""" + +class ProtocolUnitFailureError(Exception): + """Error when a ProtocolDAGResult contains an failed protocol unit.""" diff --git a/gufe/protocols/protocoldag.py b/gufe/protocols/protocoldag.py index 74e7afbd..d73d67e9 100644 --- a/gufe/protocols/protocoldag.py +++ b/gufe/protocols/protocoldag.py @@ -14,6 +14,7 @@ import networkx as nx from ..tokenization import GufeKey, GufeTokenizable +from .errors import MissingProtocolUnitError, ProtocolUnitFailureError from .protocolunit import Context, ProtocolUnit, ProtocolUnitFailure, ProtocolUnitResult @@ -211,22 +212,24 @@ def unit_to_result(self, protocol_unit: ProtocolUnit) -> ProtocolUnitResult: Raises ------ - KeyError - if either there are no results, or only failures + MissingProtocolUnitError: + if either there are no results for that protocol unit + ProtocolUnitFailureError: + if all units failed """ try: units = self._unit_result_mapping[protocol_unit] except KeyError: - raise KeyError("No such `protocol_unit` present") + raise MissingProtocolUnitError(f"No such `protocol_unit`:{protocol_unit} present") else: for u in units: if u.ok(): return u else: - raise KeyError("No success for `protocol_unit` found") + raise ProtocolUnitFailureError(f"No success for `protocol_unit`:{protocol_unit} found") def unit_to_all_results(self, protocol_unit: ProtocolUnit) -> list[ProtocolUnitResult]: - """Return all results (sucess and failure) for a given Unit. + """Return all results (success and failure) for a given Unit. Returns ------- @@ -235,19 +238,19 @@ def unit_to_all_results(self, protocol_unit: ProtocolUnit) -> list[ProtocolUnitR Raises ------ - KeyError + MissingProtocolUnitError if no results present for a given unit """ try: return self._unit_result_mapping[protocol_unit] except KeyError: - raise KeyError("No such `protocol_unit` present") + raise MissingProtocolUnitError(f"No such `protocol_unit`:{protocol_unit} present") def result_to_unit(self, protocol_unit_result: ProtocolUnitResult) -> ProtocolUnit: try: return self._result_unit_mapping[protocol_unit_result] except KeyError: - raise KeyError("No such `protocol_unit_result` present") + raise MissingProtocolUnitError(f"No such `protocol_unit_result`:{protocol_unit_result} present") def ok(self) -> bool: # ensure that for every protocol unit, there is an OK result object