Skip to content

Commit c422033

Browse files
committed
allow graceful failure of workflows when not debugging
1 parent dcecbf3 commit c422033

File tree

3 files changed

+55
-88
lines changed

3 files changed

+55
-88
lines changed

new-docs/source/examples/glm.ipynb

Lines changed: 19 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"from pathlib import Path\n",
5757
"\n",
5858
"from pydra.design import python, workflow\n",
59+
"from pydra.engine.submitter import Submitter\n",
5960
"from fileformats.generic import File, Directory\n",
6061
"from fileformats.text import Csv\n",
6162
"import pandas as pd\n",
@@ -588,8 +589,10 @@
588589
"source": [
589590
"wf = FullWorkflow(output_dir=workflow_out_dir, n_subjects=1, contrast='StopSuccess - Go')\n",
590591
"\n",
591-
"if False:\n",
592-
" results = wf(plugin='cf', n_procs=4)\n",
592+
"if __name__ == \"__main__\":\n",
593+
" with Submitter(worker='cf', n_procs=4) as sub:\n",
594+
" results = sub(wf)\n",
595+
"\n",
593596
" print(results)"
594597
]
595598
},
@@ -630,7 +633,7 @@
630633
},
631634
"outputs": [],
632635
"source": [
633-
"!ls ../outputs/6_glm"
636+
"! ls ../outputs/6_glm"
634637
]
635638
},
636639
{
@@ -641,14 +644,6 @@
641644
"### Plot figures"
642645
]
643646
},
644-
{
645-
"cell_type": "markdown",
646-
"id": "dad22ca7",
647-
"metadata": {},
648-
"source": [
649-
"#### First level contrast"
650-
]
651-
},
652647
{
653648
"cell_type": "code",
654649
"execution_count": null,
@@ -662,73 +657,19 @@
662657
"source": [
663658
"from IPython.display import Image\n",
664659
"\n",
665-
"Image(filename='../outputs/6_glm/firstlevel_contrast.jpg')"
666-
]
667-
},
668-
{
669-
"cell_type": "markdown",
670-
"id": "0cdfcc29",
671-
"metadata": {},
672-
"source": [
673-
"#### Nilearn Z map"
674-
]
675-
},
676-
{
677-
"cell_type": "code",
678-
"execution_count": null,
679-
"id": "f08aa59f",
680-
"metadata": {
681-
"tags": [
682-
"hide-input"
683-
]
684-
},
685-
"outputs": [],
686-
"source": [
687-
"Image(filename='../outputs/6_glm/nilearn_z_map.jpg')"
688-
]
689-
},
690-
{
691-
"cell_type": "markdown",
692-
"id": "ca1b896f",
693-
"metadata": {},
694-
"source": [
695-
"#### FSL Z map"
696-
]
697-
},
698-
{
699-
"cell_type": "code",
700-
"execution_count": null,
701-
"id": "7d18b6ed",
702-
"metadata": {
703-
"tags": [
704-
"hide-input"
705-
]
706-
},
707-
"outputs": [],
708-
"source": [
709-
"Image(filename='../outputs/6_glm/fsl_z_map.jpg')"
710-
]
711-
},
712-
{
713-
"cell_type": "markdown",
714-
"id": "fc68e7dc",
715-
"metadata": {},
716-
"source": [
717-
"#### Nilearn FSL comparison"
718-
]
719-
},
720-
{
721-
"cell_type": "code",
722-
"execution_count": null,
723-
"id": "a37679ff",
724-
"metadata": {
725-
"tags": [
726-
"hide-input"
727-
]
728-
},
729-
"outputs": [],
730-
"source": [
731-
"Image(filename='../outputs/6_glm/nilearn_fsl_comp.jpg')"
660+
"\n",
661+
"if not results.errored:\n",
662+
" # First-level contrast\n",
663+
" Image(filename='../outputs/6_glm/firstlevel_contrast.jpg')\n",
664+
"\n",
665+
" # Nilearn Z map\n",
666+
" Image(filename='../outputs/6_glm/nilearn_z_map.jpg')\n",
667+
"\n",
668+
" # FSL Z map\n",
669+
" Image(filename='../outputs/6_glm/fsl_z_map.jpg')\n",
670+
"\n",
671+
" # Nilearn and FSL comparison\n",
672+
" Image(filename='../outputs/6_glm/nilearn_fsl_comp.jpg')"
732673
]
733674
},
734675
{

pydra/engine/submitter.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@
2929

3030
if ty.TYPE_CHECKING:
3131
from .node import Node
32-
from .specs import TaskDef, WorkflowDef, TaskHooks
32+
from .specs import TaskDef, TaskOutputs, WorkflowDef, TaskHooks, Result
3333
from .environments import Environment
3434
from .state import State
3535

3636
DefType = ty.TypeVar("DefType", bound="TaskDef")
37+
OutputType = ty.TypeVar("OutputType", bound="TaskOutputs")
3738

3839
# Used to flag development mode of Audit
3940
develop = False
@@ -167,14 +168,34 @@ def worker(self):
167168

168169
def __call__(
169170
self,
170-
task_def: "TaskDef",
171-
name: str | None = "task",
171+
task_def: "TaskDef[OutputType]",
172172
hooks: "TaskHooks | None" = None,
173-
):
174-
"""Submitter run function."""
173+
raise_errors: bool | None = None,
174+
) -> "Result[OutputType]":
175+
"""Submitter run function.
175176
176-
if name is None:
177-
name = "task"
177+
Parameters
178+
----------
179+
task_def : :obj:`~pydra.engine.specs.TaskDef`
180+
The task definition to run
181+
hooks : :obj:`~pydra.engine.specs.TaskHooks`, optional
182+
Task hooks, callable functions called as the task is setup and torn down,
183+
by default no functions are called at the hooks
184+
raise_errors : bool, optional
185+
Whether to raise errors, by default True if the 'debug' worker is used,
186+
otherwise False
187+
188+
Returns
189+
-------
190+
result : Any
191+
The result of the task
192+
"""
193+
if raise_errors is None:
194+
raise_errors = self.worker_name == "debug"
195+
if not isinstance(raise_errors, bool):
196+
raise TypeError(
197+
f"'raise_errors' must be a boolean or None, not {type(raise_errors)}"
198+
)
178199

179200
task_def._check_rules()
180201
# If the outer task is split, create an implicit workflow to hold the split nodes
@@ -198,7 +219,7 @@ def Split(defn: TaskDef, output_types: dict):
198219
task = Task(
199220
task_def,
200221
submitter=self,
201-
name=name,
222+
name="task",
202223
environment=self.environment,
203224
hooks=hooks,
204225
)
@@ -211,11 +232,15 @@ def Split(defn: TaskDef, output_types: dict):
211232
else:
212233
self.worker.run(task, rerun=self.rerun)
213234
except Exception as e:
214-
e.add_note(
235+
msg = (
215236
f"Full crash report for {type(task_def).__name__!r} task is here: "
216237
+ str(task.output_dir / "_error.pklz")
217238
)
218-
raise e
239+
if raise_errors:
240+
e.add_note(msg)
241+
raise e
242+
else:
243+
logger.error("\nTask execution failed\n" + msg)
219244
finally:
220245
self.run_start_time = None
221246
PersistentCache().clean_up()

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ doc = [
4848
"ipython",
4949
"ipykernel",
5050
"ipywidgets",
51+
"matplotlib",
5152
"nbsphinx",
5253
"nest_asyncio",
5354
"nibabel",

0 commit comments

Comments
 (0)