Пример #1
0
def _handle_error_unrecognized_by_parser(self, calculation):
    """
    Calculation failed with an error that was not recognized by the parser and was attached
    wholesale to the warnings. We treat it as an unexpected failure and raise the exception
    """
    warnings = calculation.res.warnings
    if (any(['%%%' in w for w in warnings]) or any(['Error' in w for w in warnings])):
        raise UnexpectedCalculationFailure('PwCalculation<{}> failed due to an unknown reason'.format(calculation.pk))
Пример #2
0
    def _handle_calculation_failure(self, calculation):
        """Call the attached error handlers if any to attempt to correct the cause of the calculation failure.

        The registered error handlers will be called in order based on their priority until a handler returns a report
        that instructs to break. If the last executed error handler defines an exit code, that will be returned to
        instruct the work chain to abort. Otherwise the work chain will continue the cycle.

        :param calculation: the calculation that finished with a non-zero exit status
        :return: `ExitCode` if the work chain is to be aborted
        :raises `UnexpectedCalculationFailure`: if no error handlers were registered or no errors were handled.
        """
        is_handled = False
        handler_report = None

        if not hasattr(self, '_error_handlers') or not self._error_handlers:
            raise UnexpectedCalculationFailure('no calculation error handlers were registered')

        # Sort the handlers with a priority defined, based on their priority in reverse order
        handlers = [handler for handler in self._error_handlers if handler.priority]
        handlers = sorted(handlers, key=lambda x: x.priority, reverse=True)

        for handler in handlers:

            handler_report = handler.method(self, calculation)

            # If at least one error is handled, we consider the calculation failure handled.
            if handler_report and handler_report.is_handled:
                self.ctx.unexpected_failure = False
                is_handled = True

            # After certain error handlers, we may want to skip all other error handling
            if handler_report and handler_report.do_break:
                break

        # If none of the executed error handlers reported that they handled an error, the failure reason is unknown
        if not is_handled:
            raise UnexpectedCalculationFailure('calculation failure was not handled')

        # The last called error handler may not necessarily have returned a handler report
        if handler_report:
            return handler_report.exit_code

        return
Пример #3
0
    def _handle_calculation_failure(self, calculation):
        """
        The calculation has failed so we try to analyze the reason and change the inputs accordingly
        for the next calculation. If the calculation failed, but did so cleanly, we set it as the
        restart_calc, in all other cases we do not replace the restart_calc
        """
        try:
            outputs = calculation.out.output_parameters.get_dict()
            _ = outputs['warnings']
            _ = outputs['parser_warnings']
        except (AttributeError, KeyError) as exception:
            raise UnexpectedCalculationFailure(exception)

        is_handled = False

        # Sort the handlers based on their priority in reverse order
        handlers = sorted(self._error_handlers,
                          key=lambda x: x.priority,
                          reverse=True)

        if not handlers:
            raise UnexpectedCalculationFailure(
                'no calculation error handlers were registered')

        for handler in handlers:
            handler_report = handler.method(self, calculation)

            # If at least one error is handled, we consider the calculation failure handled
            if handler_report and handler_report.is_handled:
                self.ctx.restart_calc = calculation
                is_handled = True

            # After certain error handlers, we may want to skip all other error handling
            if handler_report and handler_report.do_break:
                break

        # If none of the executed error handlers reported that they handled an error, the failure reason is unknown
        if not is_handled:
            raise UnexpectedCalculationFailure(
                'calculation failure was not handled')

        return