Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 86e5746

Browse files
authored
Merge pull request #94 from plotly/fix-start-error
Propagate start errors.
2 parents b6dad26 + 5536652 commit 86e5746

File tree

3 files changed

+58
-23
lines changed

3 files changed

+58
-23
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ All notable changes to `jupyter-dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [UNRELEASED]
6+
### Fixed
7+
- Propagate start error message. [#94](https://github.com/plotly/jupyter-dash/pull/94)
8+
69
### Added
710

811
- Support for `Dash.run` method added in Dash 2.4.0

jupyter_dash/_stoppable_thread.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ def get_id(self):
1212

1313
def kill(self):
1414
thread_id = self.get_id()
15-
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
16-
ctypes.c_long(thread_id), ctypes.py_object(SystemExit)
17-
)
18-
if res == 0:
19-
raise ValueError(f"Invalid thread id: {thread_id}")
20-
if res > 1:
21-
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), None)
22-
raise SystemExit("Stopping thread failure")
15+
if thread_id:
16+
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
17+
ctypes.c_long(thread_id), ctypes.py_object(SystemExit)
18+
)
19+
if res == 0:
20+
raise ValueError(f"Invalid thread id: {thread_id}")
21+
if res > 1:
22+
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), None)
23+
raise SystemExit("Stopping thread failure")

jupyter_dash/jupyter_app.py

+46-15
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
import os
33
import requests
44
import flask.cli
5+
from IPython.core.display import HTML
56
from retrying import retry
67
import io
78
import re
89
import sys
910
import inspect
1011
import traceback
1112
import warnings
13+
import queue
1214

1315
from IPython import get_ipython
1416
from IPython.display import IFrame, display
@@ -298,6 +300,8 @@ def run(
298300
except ImportError:
299301
pass
300302

303+
err_q = queue.Queue()
304+
301305
@retry(
302306
stop_max_attempt_number=15,
303307
wait_exponential_multiplier=100,
@@ -308,6 +312,9 @@ def run():
308312
super_run_server(**kwargs)
309313
except SystemExit:
310314
pass
315+
except Exception as error:
316+
err_q.put(error)
317+
raise error
311318

312319
thread = StoppableThread(target=run)
313320
thread.setDaemon(True)
@@ -320,31 +327,55 @@ def run():
320327
host=host, port=port, token=JupyterDash._token
321328
)
322329

330+
def _get_error():
331+
try:
332+
err = err_q.get_nowait()
333+
if err:
334+
raise err
335+
except queue.Empty:
336+
pass
337+
323338
# Wait for app to respond to _alive endpoint
324339
@retry(
325340
stop_max_attempt_number=15,
326341
wait_exponential_multiplier=10,
327342
wait_exponential_max=1000
328343
)
329344
def wait_for_app():
330-
res = requests.get(alive_url).content.decode()
331-
if res != "Alive":
332-
url = "http://{host}:{port}".format(
333-
host=host, port=port, token=JupyterDash._token
334-
)
335-
raise OSError(
336-
"Address '{url}' already in use.\n"
337-
" Try passing a different port to run_server.".format(
338-
url=url
345+
_get_error()
346+
try:
347+
req = requests.get(alive_url)
348+
res = req.content.decode()
349+
if req.status_code != 200:
350+
raise Exception(res)
351+
352+
if res != "Alive":
353+
url = "http://{host}:{port}".format(
354+
host=host, port=port, token=JupyterDash._token
339355
)
340-
)
356+
raise OSError(
357+
"Address '{url}' already in use.\n"
358+
" Try passing a different port to run_server.".format(
359+
url=url
360+
)
361+
)
362+
except requests.ConnectionError as err:
363+
_get_error()
364+
raise err
341365

342-
wait_for_app()
366+
try:
367+
wait_for_app()
343368

344-
if JupyterDash._in_colab:
345-
self._display_in_colab(dashboard_url, port, mode, width, height)
346-
else:
347-
self._display_in_jupyter(dashboard_url, port, mode, width, height)
369+
if JupyterDash._in_colab:
370+
self._display_in_colab(dashboard_url, port, mode, width, height)
371+
else:
372+
self._display_in_jupyter(dashboard_url, port, mode, width, height)
373+
except Exception as final_error:
374+
msg = str(final_error)
375+
if msg.startswith('<!'):
376+
display(HTML(msg))
377+
else:
378+
raise final_error
348379

349380
def _display_in_colab(self, dashboard_url, port, mode, width, height):
350381
from google.colab import output

0 commit comments

Comments
 (0)