def test_failed_operation(water, result_input, opti_failure): failed = FailedOperation(garbage=water, **result_input, **opti_failure) assert isinstance(failed.error, ComputeError) assert isinstance(failed.dict(), dict) failed_json = failed.json() assert isinstance(failed_json, str) assert 'its all good' in failed_json
def test_failed_operation(water, result_input): failed = FailedOperation(extras={"garbage": water}, input_data=result_input, error={ "error_type": "expected_testing_error", "error_message": "If you see this, its all good" }) assert isinstance(failed.error, ComputeError) assert isinstance(failed.dict(), dict) failed_json = failed.json() assert isinstance(failed_json, str) assert 'its all good' in failed_json
def handle_output_metadata( output_data: Union[Dict[str, Any], 'BaseModel'], metadata: Dict[str, Any], raise_error: bool = False, return_dict: bool = True) -> Union[Dict[str, Any], 'BaseModel']: """ Fuses general metadata and output together. Returns ------- result : dict or pydantic.models.Result Output type depends on return_dict or a dict if an error was generated in model construction """ if isinstance(output_data, dict): output_fusion = output_data # Error handling else: output_fusion = output_data.dict() # Do not override if computer generates output_fusion["stdout"] = output_fusion.get("stdout", None) or metadata["stdout"] output_fusion["stderr"] = output_fusion.get("stderr", None) or metadata["stderr"] if metadata["success"] is not True: output_fusion["success"] = False output_fusion["error"] = { "error_type": metadata["error_type"], "error_message": metadata["error_message"] } # Raise an error if one exists and a user requested a raise if raise_error and (output_fusion["success"] is not True): msg = "stdout:\n{}".format(output_fusion["stdout"]) msg += "\nstderr:\n{}".format(output_fusion["stderr"]) LOGGER.info(msg) raise ValueError(output_fusion["error"]["error_message"]) # Fill out provenance datadata provenance_augments = get_provenance_augments() provenance_augments["wall_time"] = metadata["wall_time"] if "provenance" in output_fusion: output_fusion["provenance"].update(provenance_augments) else: # Add onto the augments with some missing info provenance_augments["creator"] = "QCEngine" provenance_augments["version"] = provenance_augments[ "qcengine_version"] output_fusion["provenance"] = provenance_augments if metadata["retries"] != 0: output_fusion["provenance"]["retries"] = metadata["retries"] # Make sure pydantic sparsity is upheld for val in ["stdout", "stderr"]: if output_fusion[val] is None: output_fusion.pop(val) # We need to return the correct objects; e.g. Results, Procedures if output_fusion["success"]: # This will only execute if everything went well ret = output_data.__class__(**output_fusion) else: # Should only be reachable on failures ret = FailedOperation(success=output_fusion.pop("success", False), error=output_fusion.pop("error"), input_data=output_fusion) if return_dict: return json.loads( ret.json() ) # Use Pydantic to serialize, then reconstruct as Python dict of Python Primals else: return ret
def handle_output_metadata(output_data, metadata, raise_error=False, return_dict=True): """ Fuses general metadata and output together. Returns ------- result : dict or pydantic.models.Result Output type depends on return_dict or a dict if an error was generated in model construction """ if isinstance(output_data, dict): output_fusion = output_data # Error handling else: output_fusion = output_data.dict() output_fusion["stdout"] = metadata["stdout"] output_fusion["stderr"] = metadata["stderr"] if metadata["success"] is not True: output_fusion["success"] = False output_fusion["error"] = { "error_type": "meta_error", "error_message": metadata["error_message"] } # Raise an error if one exists and a user requested a raise if raise_error and (output_fusion["success"] is not True): msg = "stdout:\n" + output_fusion["stdout"] msg += "\nstderr:\n" + output_fusion["stderr"] print(msg) raise ValueError(output_fusion["error"]["error_message"]) # Fill out provenance datadata wall_time = metadata["wall_time"] provenance_augments = config.get_provenance_augments() provenance_augments["wall_time"] = wall_time if "provenance" in output_fusion: output_fusion["provenance"].update(provenance_augments) else: # Add onto the augments with some missing info provenance_augments["creator"] = "QCEngine" provenance_augments["version"] = provenance_augments[ "qcengine_version"] output_fusion["provenance"] = provenance_augments # We need to return the correct objects; e.g. Results, Procedures if output_fusion["success"]: # This will only execute if everything went well ret = output_data.__class__(**output_fusion) else: # Should only be reachable on failures ret = FailedOperation(success=output_fusion.pop("success", False), error=output_fusion.pop("error"), input_data=output_fusion) if return_dict: return json.loads( ret.json() ) # Use Pydantic to serialize, then reconstruct as Python dict of Python Primals else: return ret