pyiron / pyiron_workflow

Graph-and-node based workflows
BSD 3-Clause "New" or "Revised" License
14 stars 1 forks source link

[patch] Allow failure #471

Closed liamhuber closed 1 month ago

liamhuber commented 1 month ago

This adds a new run argument raise_run_exceptions, and a new output signal failed to allow us to handle failure states more gracefully. Exploiting the failed signal requires manual management of the execution flow, but lets us have fallback routines in the graph flow to do something else if a node fails. It plays fine with executors. Here's an example with a graph image that is just beautiful and informative thanks to @samwaseda's recent work!

from pyiron_workflow import Workflow

wf = Workflow("test")
wf.a = Workflow.create.standard.UserInput(1)
wf.b = Workflow.create.standard.UserInput("two")
wf.c_fails = wf.a + wf.b  # Type error
wf.d_if_success = Workflow.create.standard.UserInput(0)
wf.d_if_failure = Workflow.create.standard.UserInput("But what's the question?")
wf.e_fails = Workflow.create.standard.Add(wf.d_if_failure, 42)  # Type error

wf.a >> wf.b >> wf.c_fails >> wf.d_if_success
wf.c_fails.signals.output.failed >> wf.d_if_failure >> wf.e_fails
wf.starting_nodes = [wf.a]
wf.automate_execution = False

with Workflow.create.ProcessPoolExecutor() as exe:
    wf.c_fails.executor = exe
    wf(raise_run_exceptions=False)

wf.draw(size=(10, 10))

failure

Composites now let the graph keep running until they run out of children to execute, and collect all exceptions together and raise a single FailedChildError. If instead above we had wf(raise_run_exceptions=True), we'd see the error message:

FailedChildError: /test encountered multiple errors in children: {'/test/c_fails.run': TypeError("unsupported operand type(s) for +: 'int' and 'str'"), '/test/e_fails.run': TypeError('can only concatenate str (not "int") to str')}

@samwaseda, since you've been improving the error messages too, I'm going to hit you here for review as all this is closely related.

review-notebook-app[bot] commented 1 month ago

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

github-actions[bot] commented 1 month ago

Binder :point_left: Launch a binder notebook on branch _pyiron/pyiron_workflow/allowfailure

codacy-production[bot] commented 1 month ago

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
:white_check_mark: +0.22% (target: -1.00%) :white_check_mark: 86.36%
Coverage variation details | | Coverable lines | Covered lines | Coverage | | ------------- | ------------- | ------------- | ------------- | | Common ancestor commit (f70bac981d607f4179f496cc29f72f4157eb35fb) | 3290 | 3003 | 91.28% | | | Head commit (70268fc7a795a0bbaae2a55642bb930ef4440c90) | 3304 (+14) | 3023 (+20) | 91.50% (**+0.22%**) | **Coverage variation** is the difference between the coverage for the head and common ancestor commits of the pull request branch: ` - `
Diff coverage details | | Coverable lines | Covered lines | Diff coverage | | ------------- | ------------- | ------------- | ------------- | | Pull request (#471) | 22 | 19 | **86.36%** | **Diff coverage** is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: `/ * 100%`

See your quality gate settings    Change summary preferences

Codacy stopped sending the deprecated coverage status on June 5th, 2024. Learn more

coveralls commented 1 month ago

Pull Request Test Coverage Report for Build 11017829414

Details


Files with Coverage Reduction New Missed Lines %
mixin/run.py 7 92.38%
nodes/composite.py 13 92.31%
node.py 15 90.3%
workflow.py 28 66.17%
<!-- Total: 63 -->
Totals Coverage Status
Change from base Build 10983970779: 0.2%
Covered Lines: 3023
Relevant Lines: 3304

💛 - Coveralls