# Buggy code
def modify_document(self, doc):
    """ """
    if self.failed:
        return

    module = self._runner.new_module()

    # One reason modules are stored is to prevent the module
    # from being gc'd before the document is. A symptom of a
    # gc'd module is that its globals become None. Additionally
    # stored modules are used to provide correct paths to
    # custom models resolver.
    sys.modules[module.__name__] = module
    doc._modules.append(module)

    old_doc = curdoc()
    set_curdoc(doc)
    old_io = self._monkeypatch_io()

    try:

        def post_check():
            newdoc = curdoc()
            # script is supposed to edit the doc not replace it
            if newdoc is not doc:
                raise RuntimeError(
                    "%s at '%s' replaced the output document"
                    % (self._origin, self._runner.path)
                )

        self._runner.run(module, post_check)
    finally:
        self._unmonkeypatch_io(old_io)
        set_curdoc(old_doc)


# Traceback (Exception)
(venv) $ bokeh serve myapp.py
2018-06-27 12:59:45,343 Starting Bokeh server version 0.13.0 (running on Tornado 5.0.1)
2018-06-27 12:59:45,345 Bokeh app running at: http://localhost:5006/myapp
2018-06-27 12:59:45,345 Starting Bokeh server with process id: 13979
0.5604607908584933
2018-06-27 13:00:06,274 200 GET /myapp (::1) 96.25ms
2018-06-27 13:00:06,437 101 GET /myapp/ws?bokeh-protocol-version=1.0&amp;bokeh-session-id=OxhSy81ZBM8URWfk6wp7OTH7bTictF12u6pI8o7fkIUs (::1) 0.64ms
2018-06-27 13:00:06,437 WebSocket connection opened
2018-06-27 13:00:06,438 ServerConnection created
0.6452850662545722
0.2762922805351794
2018-06-27 13:00:11,120 Error running application handler <bokeh.application.handlers.script.ScriptHandler object at 0x7feae4861a58>: boom!
File "myapp.py", line 46, in <module>:
raise Exception('boom!') Traceback (most recent call last):
File "/home/matt/Clients/QEye/venv/lib/python3.5/site-packages/bokeh/application/handlers/code_runner.py", line 163, in run
exec(self._code, module.__dict__)
File "/home/matt/Clients/QEye/isolate/myapp.py", line 46, in <module>
raise Exception('boom!')
Exception: boom!

2018-06-27 13:00:11,125 200 GET /myapp (::1) 25.45ms
2018-06-27 13:00:11,132 WebSocket connection closed: code=1001, reason=None
2018-06-27 13:00:11,207 101 GET /myapp/ws?bokeh-protocol-version=1.0&amp;bokeh-session-id=Y5IlTpoIxVs42drth0tKZonyuwGnUNM3zKK6OAG5eg6n (::1) 0.60ms
2018-06-27 13:00:11,208 WebSocket connection opened
2018-06-27 13:00:11,208 ServerConnection created

# Fixed code
def modify_document(self, doc):
    """ """

    module = self._runner.new_module()

    # If no module was returned it means the code runner has some permanent
    # unfixable problem, e.g. the configured source code has a syntax error
    if module is None:
        return

    # One reason modules are stored is to prevent the module
    # from being gc'd before the document is. A symptom of a
    # gc'd module is that its globals become None. Additionally
    # stored modules are used to provide correct paths to
    # custom models resolver.
    sys.modules[module.__name__] = module
    doc._modules.append(module)

    old_doc = curdoc()
    set_curdoc(doc)
    old_io = self._monkeypatch_io()

    try:

        def post_check():
            newdoc = curdoc()
            # script is supposed to edit the doc not replace it
            if newdoc is not doc:
                raise RuntimeError(
                    "%s at '%s' replaced the output document"
                    % (self._origin, self._runner.path)
                )

        self._runner.run(module, post_check)
    finally:
        self._unmonkeypatch_io(old_io)
        set_curdoc(old_doc)