Skip to content

Commit

Permalink
Add cell error instruction configurable (voila-dashboards#471)
Browse files Browse the repository at this point in the history
* add cell error instruction configurable in VoilaExecutePreprocessor
  • Loading branch information
aschlaep authored and maartenbreddels committed Feb 5, 2020
1 parent cef933d commit f82788a
Showing 1 changed file with 42 additions and 35 deletions.
77 changes: 42 additions & 35 deletions voila/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,9 @@
from nbconvert.preprocessors.execute import CellExecutionError, ExecutePreprocessor
from nbformat.v4 import output_from_msg

from ipykernel.jsonutil import json_clean


def strip_code_cell_errors(cell):
"""Strip any error outputs and traceback from a code cell."""
# There is no 'outputs' key for markdown cells
if 'outputs' not in cell:
return cell

outputs = cell['outputs']
from traitlets import Unicode

error_outputs = [output for output in outputs if output['output_type'] == 'error']

error_message = 'There was an error when executing cell [{}]. Please run Voila with --debug to see the error message.'.format(cell['execution_count'])

for output in error_outputs:
output['ename'] = 'ExecutionError'
output['evalue'] = 'Execution error'
output['traceback'] = [error_message]

return cell
from ipykernel.jsonutil import json_clean


def strip_code_cell_warnings(cell):
Expand All @@ -52,19 +34,6 @@ def strip_code_cell_warnings(cell):
return cell


def strip_notebook_errors(nb):
"""Strip error messages and traceback from a Notebook."""
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)
strip_code_cell_errors(cell)

return nb


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
Expand Down Expand Up @@ -146,6 +115,14 @@ def set_state(self, state):

class VoilaExecutePreprocessor(ExecutePreprocessor):
"""Execute, but respect the output widget behaviour"""
cell_error_instruction = Unicode(
'Please run Voila with --debug to see the error message.',
config=True,
help=(
'instruction given to user to debug cell errors'
)
)

def __init__(self, **kwargs):
super(VoilaExecutePreprocessor, self).__init__(**kwargs)
self.output_hook_stack = collections.defaultdict(list) # maps to list of hooks, where the last is used
Expand All @@ -160,7 +137,7 @@ def preprocess(self, nb, resources, km=None):

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

return result

Expand All @@ -176,7 +153,7 @@ def preprocess_cell(self, cell, resources, cell_index, store_history=True):
# Strip errors and traceback if not in debug mode
if should_strip_error(self.config):
strip_code_cell_warnings(cell)
strip_code_cell_errors(cell)
self.strip_code_cell_errors(cell)

return result

Expand Down Expand Up @@ -226,6 +203,36 @@ def clear_output(self, outs, msg, cell_index):
return
super(VoilaExecutePreprocessor, self).clear_output(outs, msg, cell_index)

def strip_notebook_errors(self, nb):
"""Strip error messages and traceback from a Notebook."""
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 'outputs' not in cell:
return cell

outputs = cell['outputs']

error_outputs = [output for output in outputs if output['output_type'] == 'error']

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

for output in error_outputs:
output['ename'] = 'ExecutionError'
output['evalue'] = 'Execution error'
output['traceback'] = [error_message]

return cell

def executenb(nb, cwd=None, km=None, **kwargs):
resources = {}
Expand Down

0 comments on commit f82788a

Please sign in to comment.