Skip to content

Commit

Permalink
Command not found will no longer traceback
Browse files Browse the repository at this point in the history
Previously, when a command was not found, Jupyter printed a traceback on the user:

    $ jupyter foobar
    Traceback (most recent call last):
      File "/usr/bin/jupyter", line 33, in <module>
        sys.exit(load_entry_point('jupyter-core==4.6.3', 'console_scripts', 'jupyter')())
      File "/usr/lib/python3.9/site-packages/jupyter_core/command.py", line 247, in main
        command = _jupyter_abspath(subcommand)
      File "/usr/lib/python3.9/site-packages/jupyter_core/command.py", line 133, in _jupyter_abspath
        raise Exception(
    Exception: Jupyter command `jupyter-foobar` not found.

Generally, I believe users should only see tracebacks when they are debugging
stuff or when there is an unexpected "crash".

In Fedora, such traceback is detected as crash by the automatic bug reporting tool.

Now, an error message is printed to stderr instead to provide a better UX.

Fixes #211
  • Loading branch information
hroncok committed Mar 5, 2021
1 parent 238196c commit b2a59c3
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
5 changes: 4 additions & 1 deletion jupyter_core/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ def main():
parser.print_usage(file=sys.stderr)
sys.exit("subcommand is required")

command = _jupyter_abspath(subcommand)
try:
command = _jupyter_abspath(subcommand)
except Exception as e:
sys.exit(e)

try:
_execvp(command, sys.argv[1:])
Expand Down
8 changes: 5 additions & 3 deletions jupyter_core/tests/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import sys
import sysconfig
from subprocess import check_output, CalledProcessError
from subprocess import check_output, PIPE, CalledProcessError
from unittest.mock import patch

import pytest
Expand All @@ -21,7 +21,7 @@ def get_jupyter_output(cmd):
"""Get output of a jupyter command"""
if not isinstance(cmd, list):
cmd = [cmd]
return check_output([sys.executable, '-m', 'jupyter_core'] + cmd).decode('utf8').strip()
return check_output([sys.executable, '-m', 'jupyter_core'] + cmd, stderr=PIPE).decode('utf8').strip()


def write_executable(path, source):
Expand Down Expand Up @@ -109,8 +109,10 @@ def test_help():


def test_subcommand_not_found():
with pytest.raises(CalledProcessError):
with pytest.raises(CalledProcessError) as excinfo:
get_jupyter_output('nonexistant-subcommand')
stderr = excinfo.value.stderr.decode('utf8')
assert stderr == 'Jupyter command `jupyter-nonexistant-subcommand` not found.\n'

@patch.object(sys, 'argv', [__file__] + sys.argv[1:])
def test_subcommand_list(tmpdir):
Expand Down

0 comments on commit b2a59c3

Please sign in to comment.