Jupyter magic to handle notebook exceptions
<p>I have a few long-running experiments in my Jupyter Notebooks. Because I don't know when they will finish, I add an email function to the last cell of the notebook, so I automatically get an email, when the notebook is done.</p>

<p>But when there is a random exception in one of the cells, the whole notebook stops executing and I never get any email. <strong>So I'm wondering if there is some magic function that could execute a function in case of an exception / kernel stop.</strong></p>

<p>Like</p>

<pre><code>def handle_exception(stacktrace):
    send_mail_to_myself(stacktrace)


%%in_case_of_notebook_exception handle_exception # &lt;--- this is what I'm looking for
</code></pre>

<p>The other option would be to encapsulate every cell in try-catch, right? But that's soooo tedious.</p>

<p>Thanks in advance for any suggestions.</p>

<p>@show0k gave the correct answer to my question (in regards to magic methods). Thanks a lot! :)</p>

<p>That answer inspired me to dig a little deeper and I came across an IPython method that lets you define a <strong>custom exception handler for the whole notebook</strong>.</p>

<p>I got it to work like this:</p>

<pre><code>from IPython.core.ultratb import AutoFormattedTB

# initialize the formatter for making the tracebacks into strings
itb = AutoFormattedTB(mode = 'Plain', tb_offset = 1)

# this function will be called on exceptions in any cell
def custom_exc(shell, etype, evalue, tb, tb_offset=None):

    # still show the error within the notebook, don't just swallow it
    shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset)

    # grab the traceback and make it into a list of strings
    stb = itb.structured_traceback(etype, evalue, tb)
    sstb = itb.stb2text(stb)

    print (sstb) # &lt;--- this is the variable with the traceback string
    print ("sending mail")
    send_mail_to_myself(sstb)

# this registers a custom exception handler for the whole current notebook
get_ipython().set_custom_exc((Exception,), custom_exc)
</code></pre>

<p>So this can be put into a single cell at the top of any notebook and as a result it will do the mailing in case something goes wrong.</p>

<p>Note to self / TODO: make this snippet into a little python module that can be imported into a notebook and activated via line magic.</p>

<p>Be careful though. The documentation contains a warning for this <code>set_custom_exc</code> method: "WARNING: by putting in your own exception handler into IPythonâs main execution loop, you run a very good chance of nasty crashes. This facility should only be used if you really know what you are doing."</p>

python jupyter jupyter-notebook