Georg Brandl avatar Georg Brandl committed d6faac3

#316: catch "broken pipe" OSErrors when communicating with graphviz; get stdout/stderr anyway. This happens e.g. when dot does not support the selected output format.

Comments (0)

Files changed (3)

 Release 0.6.4 (in development)
 ==============================
 
+* #316: Catch OSErrors occurring when calling graphviz with
+  arguments it doesn't understand.
+
 * Restore compatibility with Pygments >= 1.2.
 
 * #295: Fix escaping of hyperref targets in LaTeX output.

sphinx/ext/graphviz.py

 from docutils import nodes
 
 from sphinx.errors import SphinxError
-from sphinx.util import ensuredir, ENOENT
+from sphinx.util import ensuredir, ENOENT, EPIPE
 from sphinx.util.compat import Directive
 
 
 
     ensuredir(path.dirname(outfn))
 
+    # graphviz expects UTF-8 by default
+    if isinstance(code, unicode):
+        code = code.encode('utf-8')
+
     dot_args = [self.builder.config.graphviz_dot]
     dot_args.extend(self.builder.config.graphviz_dot_args)
     dot_args.extend(options)
                           self.builder.config.graphviz_dot)
         self.builder._graphviz_warned_dot = True
         return None, None
-    # graphviz expects UTF-8 by default
-    if isinstance(code, unicode):
-        code = code.encode('utf-8')
-    stdout, stderr = p.communicate(code)
+    try:
+        # Graphviz may close standard input when an error occurs,
+        # resulting in a broken pipe on communicate()
+        stdout, stderr = p.communicate(code)
+    except OSError, err:
+        if err.errno != EPIPE:
+            raise
+        # in this case, read the standard output and standard error streams
+        # directly, to get the error message(s)
+        stdout, stderr = p.stdout.read(), p.stderr.read()
+        p.wait()
     if p.returncode != 0:
         raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
                             '[stdout]\n%s' % (stderr, stdout))
 def render_dot_html(self, node, code, options, prefix='graphviz',
                     imgcls=None, alt=None):
     try:
-        fname, outfn = render_dot(self, code, options, 'png', prefix)
+        fname, outfn = render_dot(self, code, options, 'pnf', prefix)
     except GraphvizError, exc:
         self.builder.warn('dot code %r: ' % code + str(exc))
         raise nodes.SkipNode

sphinx/util/__init__.py

 # Errnos that we need.
 EEXIST = getattr(errno, 'EEXIST', 0)
 ENOENT = getattr(errno, 'ENOENT', 0)
+EPIPE  = getattr(errno, 'EPIPE', 0)
 
 # Generally useful regular expressions.
 ws_re = re.compile(r'\s+')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.