Skip to content

Commit

Permalink
Respect allow_errors parameter value
Browse files Browse the repository at this point in the history
Signed-off-by: martinRenou <[email protected]>
  • Loading branch information
martinRenou committed Jan 29, 2020
1 parent 3125f66 commit 78130b8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 45 deletions.
63 changes: 23 additions & 40 deletions voila/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,6 @@
from ipykernel.jsonutil import json_clean


def strip_code_cell_warnings(cell):
"""Strip any warning outputs and traceback from a code cell."""
if cell['cell_type'] != 'code':
return cell

outputs = cell['outputs']

cell['outputs'] = [
output for output in outputs
if output['output_type'] != 'stream' or output['name'] != 'stderr'
]

return cell


def should_strip_error(config):
"""Return True if errors should be stripped from the Notebook, False otherwise, depending on the current config."""
return 'Voila' not in config or 'log_level' not in config['Voila'] or config['Voila']['log_level'] != logging.DEBUG


class OutputWidget:
"""This class mimics a front end output widget"""
def __init__(self, comm_id, state, kernel_client, executor):
Expand Down Expand Up @@ -128,31 +108,22 @@ def __init__(self, **kwargs):
self.output_objects = {}

def preprocess(self, nb, resources, km=None):
try:
result = super(VoilaExecutePreprocessor, self).preprocess(nb, resources=resources, km=km)
except CellExecutionError as e:
self.log.error(e)
result = (nb, resources)
result = super(VoilaExecutePreprocessor, self).preprocess(nb, resources=resources, km=km)

# Strip errors and traceback if not in debug mode
if should_strip_error(self.config):
self.strip_notebook_errors(nb)
self.strip_notebook_errors(nb)

return result

def preprocess_cell(self, cell, resources, cell_index, store_history=True):
# TODO: pass store_history as a 5th argument when we can require nbconver >=5.6.1
# result = super(VoilaExecutePreprocessor, self).preprocess_cell(cell, resources, cell_index, store_history)
try:
# TODO: pass store_history as a 5th argument when we can require nbconver >=5.6.1
# result = super(VoilaExecutePreprocessor, self).preprocess_cell(cell, resources, cell_index, store_history)
result = super(VoilaExecutePreprocessor, self).preprocess_cell(cell, resources, cell_index)
except CellExecutionError as e:
self.log.error(e)
result = (cell, resources)

# Strip errors and traceback if not in debug mode
if should_strip_error(self.config):
strip_code_cell_warnings(cell)
self.strip_code_cell_errors(cell)
raise e

self.strip_code_cell_errors(cell)

return result

Expand Down Expand Up @@ -202,27 +173,39 @@ def clear_output(self, outs, msg, cell_index):
return
super(VoilaExecutePreprocessor, self).clear_output(outs, msg, cell_index)

@property
def should_strip_error(self):
"""Return True if errors should be stripped from the Notebook, False otherwise, depending on the current config."""
return 'Voila' not in self.config or 'log_level' not in self.config['Voila'] or self.config['Voila']['log_level'] != logging.DEBUG

def strip_notebook_errors(self, nb):
"""Strip error messages and traceback from a Notebook."""
if not self.should_strip_error:
return nb

cells = nb['cells']

code_cells = [cell for cell in cells if cell['cell_type'] == 'code']

for cell in code_cells:
strip_code_cell_warnings(cell)
self.strip_code_cell_errors(cell)

return nb

def strip_code_cell_errors(self, cell):
"""Strip any error outputs and traceback from a code cell."""
# There is no 'outputs' key for markdown cells
if cell['cell_type'] != 'code':
if not self.should_strip_error or cell['cell_type'] != 'code':
return cell

outputs = cell['outputs']
# Strip warnings
cell['outputs'] = [
output for output in cell['outputs']
if output['output_type'] != 'stream' or output['name'] != 'stderr'
]

error_outputs = [output for output in outputs if output['output_type'] == 'error']
# Strip errors
error_outputs = [output for output in cell['outputs'] if output['output_type'] == 'error']

error_message = 'There was an error when executing cell [{}]. {}'.format(cell['execution_count'], self.cell_error_instruction)

Expand Down
19 changes: 14 additions & 5 deletions voila/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# #
# The full license is in the file LICENSE, distributed with this software. #
#############################################################################

import os

import tornado.web
Expand All @@ -17,6 +16,7 @@
import nbformat

from nbconvert.preprocessors import ClearOutputPreprocessor
from nbconvert.preprocessors.execute import CellExecutionError

from .execute import executenb, VoilaExecutePreprocessor
from .exporter import VoilaExporter
Expand Down Expand Up @@ -121,7 +121,11 @@ def _jinja_kernel_start(self):

def _jinja_notebook_execute(self, nb, kernel_id):
km = self.kernel_manager.get_kernel(kernel_id)
result = executenb(nb, km=km, cwd=self.cwd, config=self.traitlet_config)
try:
result = executenb(nb, km=km, cwd=self.cwd, config=self.traitlet_config)
except CellExecutionError as e:
self.log.error(e)
raise tornado.web.HTTPError(500, 'There was an error executing the Notebook')
# we modify the notebook in place, since the nb variable cannot be reassigned it seems in jinja2
# e.g. if we do {% with nb = notebook_execute(nb, kernel_id) %}, the base template/blocks will not
# see the updated variable (it seems to be local to our block)
Expand All @@ -136,9 +140,14 @@ def _jinja_cell_generator(self, nb, kernel_id):

with ep.setup_preprocessor(nb, resources, km=km):
for cell_idx, cell in enumerate(nb.cells):
res = ep.preprocess_cell(cell, resources, cell_idx, store_history=False)

yield res[0]
try:
ep.preprocess_cell(cell, resources, cell_idx, store_history=False)

yield cell
except CellExecutionError as e:
yield cell
self.log.error(e)
break

# @tornado.gen.coroutine
async def load_notebook(self, path):
Expand Down

0 comments on commit 78130b8

Please sign in to comment.