def papermill_process(self, nb_man, resources):
<EOL>nb = nb_man.nb<EOL>for index, cell in enumerate(nb.cells):<EOL><INDENT>try:<EOL><INDENT>nb_man.cell_start(cell, index)<EOL>if not cell.source:<EOL><INDENT>continue<EOL><DEDENT>nb.cells[index], resources = self.preprocess_cell(cell, resources, index)<EOL><DEDENT>except CellExecutionError as ex:<EOL><INDENT>nb_man.cell_exception(nb.cells[index], cell_index=index, exception=ex)<EOL>break<EOL><DEDENT>finally:<EOL><INDENT>nb_man.cell_complete(nb.cells[index], cell_index=index)<EOL><DEDENT><DEDENT>return nb, resources<EOL>
This function acts as a replacement for the grandparent's `preprocess`
method.

We are doing this for the following reasons:

1. Notebooks will stop executing when they encounter a failure but not
   raise a `CellException`. This allows us to save the notebook with the
   traceback even though a `CellExecutionError` was encountered.

2. We want to write the notebook as cells are executed. We inject our
   logic for that here.

3. We want to include timing and execution status information with the
   metadata of each cell.

Parameters
----------
nb_man : NotebookExecutionManager
    Engine wrapper of notebook being converted
resources : dictionary
    Additional resources used in the conversion process.  Allows
    preprocessors to pass variables into the Jinja engine.