|
9 | 9 |
|
10 | 10 | import os |
11 | 11 | import os.path as op |
| 12 | +from pathlib import Path |
12 | 13 | import shutil |
13 | 14 | import socket |
14 | 15 | from copy import deepcopy |
|
30 | 31 | load_json, |
31 | 32 | emptydirs, |
32 | 33 | savepkl, |
33 | | - indirectory, |
34 | 34 | silentrm, |
35 | 35 | ) |
36 | 36 |
|
@@ -98,7 +98,7 @@ def __init__( |
98 | 98 | run_without_submitting=False, |
99 | 99 | n_procs=None, |
100 | 100 | mem_gb=0.20, |
101 | | - **kwargs |
| 101 | + **kwargs, |
102 | 102 | ): |
103 | 103 | """ |
104 | 104 | Parameters |
@@ -697,79 +697,56 @@ def _run_command(self, execute, copyfiles=True): |
697 | 697 | ) |
698 | 698 | return result |
699 | 699 |
|
700 | | - outdir = self.output_dir() |
701 | | - # Run command: either execute is true or load_results failed. |
702 | | - result = InterfaceResult( |
703 | | - interface=self._interface.__class__, |
704 | | - runtime=Bunch( |
705 | | - cwd=outdir, |
706 | | - returncode=1, |
707 | | - environ=dict(os.environ), |
708 | | - hostname=socket.gethostname(), |
709 | | - ), |
710 | | - inputs=self._interface.inputs.get_traitsfree(), |
711 | | - ) |
712 | | - |
| 700 | + outdir = Path(self.output_dir()) |
713 | 701 | if copyfiles: |
714 | 702 | self._originputs = deepcopy(self._interface.inputs) |
715 | 703 | self._copyfiles_to_wd(execute=execute) |
716 | 704 |
|
717 | | - message = '[Node] Running "{}" ("{}.{}")'.format( |
718 | | - self.name, self._interface.__module__, self._interface.__class__.__name__ |
| 705 | + # Run command: either execute is true or load_results failed. |
| 706 | + logger.info( |
| 707 | + f'[Node] Executing "{self.name}" <{self._interface.__module__}' |
| 708 | + f".{self._interface.__class__.__name__}>" |
| 709 | + ) |
| 710 | + # Invoke core run method of the interface ignoring exceptions |
| 711 | + result = self._interface.run(cwd=outdir, ignore_exception=True) |
| 712 | + logger.info( |
| 713 | + f'[Node] Finished "{self.name}", elapsed time {result.runtime.duration}s.' |
719 | 714 | ) |
| 715 | + |
720 | 716 | if issubclass(self._interface.__class__, CommandLine): |
721 | | - try: |
722 | | - with indirectory(outdir): |
723 | | - cmd = self._interface.cmdline |
724 | | - except Exception as msg: |
725 | | - result.runtime.stderr = "{}\n\n{}".format( |
726 | | - getattr(result.runtime, "stderr", ""), msg |
727 | | - ) |
728 | | - _save_resultfile( |
729 | | - result, |
730 | | - outdir, |
731 | | - self.name, |
732 | | - rebase=str2bool(self.config["execution"]["use_relative_paths"]), |
733 | | - ) |
734 | | - raise |
735 | | - cmdfile = op.join(outdir, "command.txt") |
736 | | - with open(cmdfile, "wt") as fd: |
737 | | - print(cmd + "\n", file=fd) |
738 | | - message += ", a CommandLine Interface with command:\n{}".format(cmd) |
739 | | - logger.info(message) |
740 | | - try: |
741 | | - result = self._interface.run(cwd=outdir) |
742 | | - except Exception as msg: |
743 | | - result.runtime.stderr = "%s\n\n%s".format( |
744 | | - getattr(result.runtime, "stderr", ""), msg |
745 | | - ) |
746 | | - _save_resultfile( |
747 | | - result, |
| 717 | + # Write out command line as it happened |
| 718 | + (outdir / "command.txt").write_text(f"{result.runtime.cmdline}\n") |
| 719 | + |
| 720 | + exc_tb = getattr(result, "traceback", None) |
| 721 | + |
| 722 | + if not exc_tb: |
| 723 | + # Clean working directory if no errors |
| 724 | + dirs2keep = None |
| 725 | + if isinstance(self, MapNode): |
| 726 | + dirs2keep = [op.join(outdir, "mapflow")] |
| 727 | + |
| 728 | + result.outputs = clean_working_directory( |
| 729 | + result.outputs, |
748 | 730 | outdir, |
749 | | - self.name, |
750 | | - rebase=str2bool(self.config["execution"]["use_relative_paths"]), |
| 731 | + self._interface.inputs, |
| 732 | + self.needed_outputs, |
| 733 | + self.config, |
| 734 | + dirs2keep=dirs2keep, |
751 | 735 | ) |
752 | | - raise |
753 | | - |
754 | | - dirs2keep = None |
755 | | - if isinstance(self, MapNode): |
756 | | - dirs2keep = [op.join(outdir, "mapflow")] |
757 | 736 |
|
758 | | - result.outputs = clean_working_directory( |
759 | | - result.outputs, |
760 | | - outdir, |
761 | | - self._interface.inputs, |
762 | | - self.needed_outputs, |
763 | | - self.config, |
764 | | - dirs2keep=dirs2keep, |
765 | | - ) |
| 737 | + # Store results file under all circumstances |
766 | 738 | _save_resultfile( |
767 | 739 | result, |
768 | 740 | outdir, |
769 | 741 | self.name, |
770 | 742 | rebase=str2bool(self.config["execution"]["use_relative_paths"]), |
771 | 743 | ) |
772 | 744 |
|
| 745 | + if exc_tb: |
| 746 | + raise RuntimeError( |
| 747 | + f"Exception raised while executing Node {self.name}.\n\n{result.runtime.traceback}" |
| 748 | + ) |
| 749 | + |
773 | 750 | return result |
774 | 751 |
|
775 | 752 | def _copyfiles_to_wd(self, execute=True, linksonly=False): |
|
0 commit comments