mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
#2695: better error handling for setup_command
This commit is contained in:
parent
fae9eb7784
commit
ca5ad2d541
@ -55,6 +55,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()
|
||||
@ -243,52 +293,6 @@ def main(argv):
|
||||
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
|
||||
except (Exception, KeyboardInterrupt) as exc:
|
||||
handle_exception(app, opts, exc, error)
|
||||
return 1
|
||||
|
@ -15,15 +15,14 @@ from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from six import StringIO, string_types
|
||||
from distutils.cmd import Command
|
||||
from distutils.errors import DistutilsOptionError, DistutilsExecError
|
||||
|
||||
from six import StringIO, string_types
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.util.console import darkred, nocolor, color_terminal
|
||||
from sphinx.cmdline import handle_exception
|
||||
from sphinx.util.console import nocolor, color_terminal
|
||||
from sphinx.util.osutil import abspath
|
||||
|
||||
|
||||
@ -99,6 +98,8 @@ class BuildDoc(Command):
|
||||
self.config_dir = None
|
||||
self.link_index = False
|
||||
self.copyright = ''
|
||||
self.verbosity = 0
|
||||
self.traceback = False
|
||||
|
||||
def _guess_source_dir(self):
|
||||
for guess in ('doc', 'docs'):
|
||||
@ -173,21 +174,10 @@ class BuildDoc(Command):
|
||||
if app.statuscode:
|
||||
raise DistutilsExecError(
|
||||
'caused by %s builder.' % app.builder.name)
|
||||
except Exception as err:
|
||||
if self.pdb:
|
||||
import pdb
|
||||
print(darkred('Exception occurred while building, starting debugger:'),
|
||||
file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
pdb.post_mortem(sys.exc_info()[2])
|
||||
else:
|
||||
from docutils.utils import SystemMessage
|
||||
if isinstance(err, SystemMessage):
|
||||
print(darkred('reST markup error:'), file=sys.stderr)
|
||||
print(err.args[0].encode('ascii', 'backslashreplace'),
|
||||
file=sys.stderr)
|
||||
else:
|
||||
raise
|
||||
except Exception as exc:
|
||||
handle_exception(app, self, exc, sys.stderr)
|
||||
if not self.pdb:
|
||||
raise SystemExit(1)
|
||||
|
||||
if self.link_index:
|
||||
src = app.config.master_doc + app.builder.out_suffix
|
||||
|
Loading…
Reference in New Issue
Block a user