|
6 | 6 | import subprocess |
7 | 7 | from typing import Any, Callable, Iterable, Iterator, Mapping, Sequence, TypeVar, Union |
8 | 8 |
|
| 9 | +import mkdocs.exceptions |
9 | 10 | import mkdocs.utils |
10 | 11 | from cached_property import cached_property |
11 | 12 | from mkdocstrings.handlers.base import BaseCollector, CollectionError |
12 | 13 |
|
13 | 14 | from .items import DocConstant, DocItem, DocMapping, DocMethod, DocModule, DocType |
14 | 15 |
|
| 16 | +try: |
| 17 | + from mkdocs.exceptions import PluginError |
| 18 | +except ImportError: |
| 19 | + PluginError = SystemExit |
| 20 | + |
15 | 21 | log = logging.getLogger(f"mkdocs.plugins.{__name__}") |
16 | 22 | log.addFilter(mkdocs.utils.warning_filter) |
17 | 23 |
|
@@ -47,11 +53,19 @@ def __init__(self, crystal_docs_flags: Sequence[str] = ()): |
47 | 53 | self._proc = subprocess.Popen(command, stdout=subprocess.PIPE) |
48 | 54 | self._collected = collections.Counter() |
49 | 55 |
|
| 56 | + # pytype: disable=bad-return-type |
50 | 57 | @cached_property |
51 | 58 | def root(self) -> DocModule: |
52 | 59 | """The top-level namespace, represented as a fake module.""" |
53 | | - with self._proc: |
54 | | - return DocModule(json.load(self._proc.stdout)["program"], None, None) |
| 60 | + try: |
| 61 | + with self._proc: |
| 62 | + return DocModule(json.load(self._proc.stdout)["program"], None, None) |
| 63 | + finally: |
| 64 | + if self._proc.returncode: |
| 65 | + cmd = " ".join(shlex.quote(arg) for arg in self._proc.args) |
| 66 | + raise PluginError(f"Command `{cmd}` exited with status {self._proc.returncode}") |
| 67 | + |
| 68 | + # pytype: enable=bad-return-type |
55 | 69 |
|
56 | 70 | def collect(self, identifier: str, config: Mapping[str, Any]) -> "DocView": |
57 | 71 | """[Find][mkdocstrings.handlers.crystal.items.DocItem.lookup] an item by its identifier. |
|
0 commit comments