Skip to content

Commit

Permalink
refactor: Improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Feb 15, 2022
1 parent 563469b commit 7b15a51
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 23 deletions.
4 changes: 4 additions & 0 deletions src/griffe/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ class GriffeError(Exception):
"""The base exception for all Griffe errors."""


class LoadingError(GriffeError):
"""The base exception for all Griffe errors."""


class NameResolutionError(GriffeError):
"""Exception for names that cannot be resolved in a object scope."""

Expand Down
70 changes: 47 additions & 23 deletions src/griffe/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from griffe.collections import LinesCollection, ModulesCollection
from griffe.dataclasses import Alias, Kind, Module, Object
from griffe.docstrings.parsers import Parser
from griffe.exceptions import AliasResolutionError, CyclicAliasError, UnimportableModuleError
from griffe.exceptions import AliasResolutionError, CyclicAliasError, LoadingError, UnimportableModuleError
from griffe.finder import ModuleFinder
from griffe.logger import get_logger
from griffe.stats import stats
Expand Down Expand Up @@ -112,25 +112,33 @@ def load_module(
submodules: Whether to recurse on the submodules.
try_relative_path: Whether to try finding the module as a relative path.
Raises:
LoadingError: When loading a module failed for various reasons.
Returns:
A module.
"""
module_name: str
if module in _builtin_modules:
logger.debug(f"{module} is a builtin module: inspecting")
module_name = module
module_name = module # type: ignore[assignment]
top_module = self._inspect_module(module) # type: ignore[arg-type]
return self._store_and_return(module_name, top_module)

try:
module_name, package = self.finder.find_spec(module, try_relative_path)
except ModuleNotFoundError:
logger.debug(f"Could not find {module}: trying inspection")
module_name = module # type: ignore[assignment]
top_module = self._inspect_module(module) # type: ignore[arg-type]
else:
try:
module_name, package = self.finder.find_spec(module, try_relative_path)
except ModuleNotFoundError:
logger.debug(f"Could not find {module}: trying inspection")
module_name = module
top_module = self._inspect_module(module) # type: ignore[arg-type]
else:
logger.debug(f"Found {module}: visiting")
top_module = self._load_module_path(package.name, package.path, submodules=submodules)
self.modules_collection[top_module.path] = top_module
return self.modules_collection[module_name] # type: ignore[index]
logger.debug(f"Found {module}: loading")
try: # noqa: WPS505
top_module = self._load_module(package.name, package.path, submodules=submodules)
except LoadingError as error: # noqa: WPS440
logger.error(str(error))
raise
return self._store_and_return(module_name, top_module)

def resolve_aliases( # noqa: WPS231
self,
Expand Down Expand Up @@ -268,6 +276,28 @@ def stats(self) -> dict:
"""
return {**stats(self), **self._time_stats}

def _store_and_return(self, name: str, module: Module) -> Module:
self.modules_collection[module.path] = module
return self.modules_collection[name] # type: ignore[index]

def _load_module( # noqa: WPS238
self,
module_name: str,
module_path: Path | list[Path],
submodules: bool = True,
parent: Module | None = None,
) -> Module:
try: # noqa: WPS225
return self._load_module_path(module_name, module_path, submodules, parent)
except SyntaxError as error: # noqa: WPS440
raise LoadingError(f"Syntax error: {error}") from error
except ImportError as error: # noqa: WPS440
raise LoadingError(f"Import error: {error}") from error
except UnicodeDecodeError as error: # noqa: WPS440
raise LoadingError(f"UnicodeDecodeError when loading {module_path}: {error}") from error
except OSError as error: # noqa: WPS440
raise LoadingError(f"OSError when loading {module_path}: {error}") from error

def _load_module_path(
self,
module_name: str,
Expand Down Expand Up @@ -299,18 +329,12 @@ def _load_submodule(self, module: Module, subparts: tuple[str, ...], subpath: Pa
# TODO: maybe increase level to WARNING
logger.debug(f"{error}. Missing __init__ module?")
return
try: # noqa: WPS225
member_parent[subparts[-1]] = self._load_module_path(
try:
member_parent[subparts[-1]] = self._load_module(
subparts[-1], subpath, submodules=False, parent=member_parent
)
except SyntaxError as error: # noqa: WPS440
logger.debug(f"Syntax error: {error}")
except ImportError as error: # noqa: WPS440
logger.debug(f"Import error: {error}")
except UnicodeDecodeError as error: # noqa: WPS440
logger.debug(f"UnicodeDecodeError when loading {subpath}: {error}")
except OSError as error: # noqa: WPS440
logger.debug(f"OSError when loading {subpath}: {error}")
except LoadingError as error: # noqa: WPS440
logger.debug(str(error))

def _create_module(self, module_name: str, module_path: Path | list[Path]) -> Module:
return Module(
Expand Down

0 comments on commit 7b15a51

Please sign in to comment.