[Python-checkins] r61541 - in doctools/trunk/sphinx: __init__.py builder.py util/__init__.py

georg.brandl python-checkins at python.org
Tue Mar 18 20:17:57 CET 2008


Author: georg.brandl
Date: Tue Mar 18 20:17:56 2008
New Revision: 61541

Modified:
   doctools/trunk/sphinx/__init__.py
   doctools/trunk/sphinx/builder.py
   doctools/trunk/sphinx/util/__init__.py
Log:
Improve handling of exceptions.


Modified: doctools/trunk/sphinx/__init__.py
==============================================================================
--- doctools/trunk/sphinx/__init__.py	(original)
+++ doctools/trunk/sphinx/__init__.py	Tue Mar 18 20:17:56 2008
@@ -12,11 +12,15 @@
 import os
 import sys
 import getopt
+import traceback
 from os import path
 from cStringIO import StringIO
 
+from docutils.utils import SystemMessage
+
+from sphinx.util import format_exception_cut_frames, save_traceback
 from sphinx.application import Sphinx
-from sphinx.util.console import nocolor
+from sphinx.util.console import darkred, nocolor
 
 __revision__ = '$Revision$'
 __version__ = '0.1.' + __revision__[11:-2]
@@ -27,8 +31,9 @@
         print >>sys.stderr, msg
         print >>sys.stderr
     print >>sys.stderr, """\
-usage: %s [options] sourcedir outdir [filenames...]"
-options: -b <builder> -- builder to use; default is html
+Sphinx v%s
+Usage: %s [options] sourcedir outdir [filenames...]"
+Options: -b <builder> -- builder to use; default is html
          -a        -- write all files; default is to only write new and changed files
          -E        -- don't use a saved environment, always read all files
          -d <path> -- path for the cached environment and doctree files
@@ -37,10 +42,10 @@
          -N        -- do not do colored output
          -q        -- no output on stdout, just warnings on stderr
          -P        -- run Pdb on exception
-modi:
+Modi:
 * without -a and without filenames, write new and changed files.
 * with -a, write all files.
-* with filenames, write these.""" % (argv[0],)
+* with filenames, write these.""" % (__version__, argv[0])
 
 
 def main(argv=sys.argv):
@@ -104,24 +109,43 @@
         elif opt == '-P':
             use_pdb = True
 
-    app = Sphinx(srcdir, outdir, doctreedir, buildername,
-                 confoverrides, status, sys.stderr, freshenv)
-    if not app.builder:
-        return 1
-
     try:
+        app = Sphinx(srcdir, outdir, doctreedir, buildername,
+                     confoverrides, status, sys.stderr, freshenv)
+        if not app.builder:
+            return 1
+
         if all_files:
             app.builder.build_all()
         elif filenames:
             app.builder.build_specific(filenames)
         else:
             app.builder.build_update()
+    except Exception, err:
+        if use_pdb:
+            import pdb
+            print >>sys.stderr, darkred('Exception occurred while building, '
+                                        'starting debugger:')
+            traceback.print_exc()
+            pdb.post_mortem(sys.exc_info()[2])
+        else:
+            if isinstance(err, SystemMessage):
+                print >>sys.stderr, darkred('reST markup error:')
+                print >>sys.stderr, str(err)
+            else:
+                print >>sys.stderr, darkred('Exception occurred:')
+                print >>sys.stderr, format_exception_cut_frames().rstrip()
+                tbpath = save_traceback()
+                print >>sys.stderr, darkred('The full traceback has been saved '
+                                            'in %s, if you want to report the '
+                                            'issue to the author.' % tbpath)
+                print >>sys.stderr, ('Please also report this if it was a user '
+                                     'error, so that a better error message '
+                                     'can be provided next time.')
+                print >>sys.stderr, 'Send reports to georg at python.org. Thanks!'
     except:
-        if not use_pdb:
-            raise
-        import pdb, traceback
-        traceback.print_exc()
-        pdb.post_mortem(sys.exc_info()[2])
+        # catches BaseExceptions in 2.5 -- SystemExit, KeyboardInterrupt
+        pass
 
 
 if __name__ == '__main__':

Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py	(original)
+++ doctools/trunk/sphinx/builder.py	Tue Mar 18 20:17:56 2008
@@ -56,6 +56,7 @@
         self.warn = app.warn
         self.info = app.info
         self.config = app.config
+        1/0
 
         # if None, this is set in load_env()
         self.env = env
@@ -240,11 +241,7 @@
         self.env.set_warnfunc(warnings.append)
         for docname in self.status_iterator(sorted(docnames),
                                             'writing output... ', darkgreen):
-            try:
-                doctree = self.env.get_and_resolve_doctree(docname, self)
-            except Exception, err:
-                warnings.append('%s:: doctree not found!' % docname)
-                continue
+            doctree = self.env.get_and_resolve_doctree(docname, self)
             self.write_doc(docname, doctree)
         for warning in warnings:
             if warning.strip():

Modified: doctools/trunk/sphinx/util/__init__.py
==============================================================================
--- doctools/trunk/sphinx/util/__init__.py	(original)
+++ doctools/trunk/sphinx/util/__init__.py	Tue Mar 18 20:17:56 2008
@@ -12,6 +12,7 @@
 import os
 import sys
 import fnmatch
+import tempfile
 import traceback
 from os import path
 
@@ -120,3 +121,27 @@
     if i != -1:
         return s[:i], s[i+len(t):]
     return '', s
+
+
+def format_exception_cut_frames(x=1):
+    """
+    Format an exception with traceback, but only the last x frames.
+    """
+    typ, val, tb = sys.exc_info()
+    #res = ['Traceback (most recent call last):\n']
+    res = []
+    tbres = traceback.format_tb(tb)
+    res += tbres[-x:]
+    res += traceback.format_exception_only(typ, val)
+    return ''.join(res)
+
+
+def save_traceback():
+    """
+    Save the current exception's traceback in a temporary file.
+    """
+    exc = traceback.format_exc()
+    fd, path = tempfile.mkstemp('.log', 'sphinx-err-')
+    os.write(fd, exc)
+    os.close(fd)
+    return path


More information about the Python-checkins mailing list