diff options
Diffstat (limited to 'sphinx/cmdline.py')
-rw-r--r-- | sphinx/cmdline.py | 114 |
1 files changed, 60 insertions, 54 deletions
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index c4832f1c2..0d85767e4 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -23,6 +23,7 @@ from sphinx.errors import SphinxError from sphinx.application import Sphinx from sphinx.util import Tee, format_exception_cut_frames, save_traceback from sphinx.util.console import red, nocolor, color_terminal +from sphinx.util.docutils import docutils_namespace from sphinx.util.osutil import abspath, fs_encoding from sphinx.util.pycompat import terminal_safe @@ -55,6 +56,56 @@ class MyFormatter(optparse.IndentedHelpFormatter): return "\n".join(result) +def handle_exception(app, opts, exception, stderr=sys.stderr): + if opts.pdb: + import pdb + print(red('Exception occurred while building, starting debugger:'), + file=stderr) + traceback.print_exc() + pdb.post_mortem(sys.exc_info()[2]) + else: + print(file=stderr) + if opts.verbosity or opts.traceback: + traceback.print_exc(None, stderr) + print(file=stderr) + if isinstance(exception, KeyboardInterrupt): + print('interrupted!', file=stderr) + elif isinstance(exception, SystemMessage): + print(red('reST markup error:'), file=stderr) + print(terminal_safe(exception.args[0]), file=stderr) + elif isinstance(exception, SphinxError): + print(red('%s:' % exception.category), file=stderr) + print(terminal_safe(text_type(exception)), file=stderr) + elif isinstance(exception, UnicodeError): + print(red('Encoding error:'), file=stderr) + print(terminal_safe(text_type(exception)), file=stderr) + tbpath = save_traceback(app) + print(red('The full traceback has been saved in %s, if you want ' + 'to report the issue to the developers.' % tbpath), + file=stderr) + elif isinstance(exception, RuntimeError) and 'recursion depth' in str(exception): + print(red('Recursion error:'), file=stderr) + print(terminal_safe(text_type(exception)), file=stderr) + print(file=stderr) + print('This can happen with very large or deeply nested source ' + 'files. You can carefully increase the default Python ' + 'recursion limit of 1000 in conf.py with e.g.:', file=stderr) + print(' import sys; sys.setrecursionlimit(1500)', file=stderr) + else: + print(red('Exception occurred:'), file=stderr) + print(format_exception_cut_frames().rstrip(), file=stderr) + tbpath = save_traceback(app) + print(red('The full traceback has been saved in %s, if you ' + 'want to report the issue to the developers.' % tbpath), + file=stderr) + print('Please also report this if it was a user error, so ' + 'that a better error message can be provided next time.', + file=stderr) + print('A bug report can be filed in the tracker at ' + '<https://github.com/sphinx-doc/sphinx/issues>. Thanks!', + file=stderr) + + def main(argv): if not color_terminal(): nocolor() @@ -238,57 +289,12 @@ def main(argv): app = None try: - app = Sphinx(srcdir, confdir, outdir, doctreedir, opts.builder, - confoverrides, status, warning, opts.freshenv, - opts.warningiserror, opts.tags, opts.verbosity, opts.jobs) - app.build(opts.force_all, filenames) - return app.statuscode - except (Exception, KeyboardInterrupt) as err: - if opts.pdb: - import pdb - print(red('Exception occurred while building, starting debugger:'), - file=error) - traceback.print_exc() - pdb.post_mortem(sys.exc_info()[2]) - else: - print(file=error) - if opts.verbosity or opts.traceback: - traceback.print_exc(None, error) - print(file=error) - if isinstance(err, KeyboardInterrupt): - print('interrupted!', file=error) - elif isinstance(err, SystemMessage): - print(red('reST markup error:'), file=error) - print(terminal_safe(err.args[0]), file=error) - elif isinstance(err, SphinxError): - print(red('%s:' % err.category), file=error) - print(terminal_safe(text_type(err)), file=error) - elif isinstance(err, UnicodeError): - print(red('Encoding error:'), file=error) - print(terminal_safe(text_type(err)), file=error) - tbpath = save_traceback(app) - print(red('The full traceback has been saved in %s, if you want ' - 'to report the issue to the developers.' % tbpath), - file=error) - elif isinstance(err, RuntimeError) and 'recursion depth' in str(err): - print(red('Recursion error:'), file=error) - print(terminal_safe(text_type(err)), file=error) - print(file=error) - print('This can happen with very large or deeply nested source ' - 'files. You can carefully increase the default Python ' - 'recursion limit of 1000 in conf.py with e.g.:', file=error) - print(' import sys; sys.setrecursionlimit(1500)', file=error) - else: - print(red('Exception occurred:'), file=error) - print(format_exception_cut_frames().rstrip(), file=error) - tbpath = save_traceback(app) - print(red('The full traceback has been saved in %s, if you ' - 'want to report the issue to the developers.' % tbpath), - file=error) - print('Please also report this if it was a user error, so ' - 'that a better error message can be provided next time.', - file=error) - print('A bug report can be filed in the tracker at ' - '<https://github.com/sphinx-doc/sphinx/issues>. Thanks!', - file=error) - return 1 + with docutils_namespace(): + app = Sphinx(srcdir, confdir, outdir, doctreedir, opts.builder, + confoverrides, status, warning, opts.freshenv, + opts.warningiserror, opts.tags, opts.verbosity, opts.jobs) + app.build(opts.force_all, filenames) + return app.statuscode + except (Exception, KeyboardInterrupt) as exc: + handle_exception(app, opts, exc, error) + return 1 |