diff --git a/papermill/exceptions.py b/papermill/exceptions.py index e8988d93..3f42f3c3 100644 --- a/papermill/exceptions.py +++ b/papermill/exceptions.py @@ -20,7 +20,7 @@ class PapermillMissingParameterException(PapermillException): class PapermillExecutionError(PapermillException): """Raised when an exception is encountered in a notebook.""" - def __init__(self, cell_index, exec_count, source, ename, evalue, traceback): + def __init__(self, cell_index, exec_count, source, ename, evalue, traceback, output_notebook=None): args = cell_index, exec_count, source, ename, evalue, traceback self.cell_index = cell_index self.exec_count = exec_count @@ -28,6 +28,7 @@ def __init__(self, cell_index, exec_count, source, ename, evalue, traceback): self.ename = ename self.evalue = evalue self.traceback = traceback + self.output_notebook = output_notebook super().__init__(*args) diff --git a/papermill/execute.py b/papermill/execute.py index eb76cc34..f8473bd3 100644 --- a/papermill/execute.py +++ b/papermill/execute.py @@ -211,6 +211,7 @@ def raise_for_execution_errors(nb, output_path): ename=output.ename, evalue=output.evalue, traceback=output.traceback, + output_notebook=nb, ) break diff --git a/papermill/tests/test_execute.py b/papermill/tests/test_execute.py index 09600d64..9d2098d0 100644 --- a/papermill/tests/test_execute.py +++ b/papermill/tests/test_execute.py @@ -31,6 +31,13 @@ def setUp(self): def tearDown(self): shutil.rmtree(self.test_dir) + def test_execution_error_includes_output_notebook(self): + notebook_name = 'broken.ipynb' + nb_test_executed_fname = os.path.join(self.test_dir, f'output_{notebook_name}') + with self.assertRaises(PapermillExecutionError) as err: + execute_notebook(get_notebook_path(notebook_name), nb_test_executed_fname) + self.assertIsInstance(err.exception.output_notebook, nbformat.NotebookNode) + @patch(f"{engines.__name__}.PapermillNotebookClient") def test_start_timeout(self, preproc_mock): execute_notebook(self.notebook_path, self.nb_test_executed_fname, start_timeout=123)