diff --git a/PFERD/__main__.py b/PFERD/__main__.py index d588836..9a307b2 100644 --- a/PFERD/__main__.py +++ b/PFERD/__main__.py @@ -115,7 +115,12 @@ def main() -> None: dump_config(args, config) exit() - pferd = Pferd(config) + try: + pferd = Pferd(config) + except ConfigOptionError as e: + log.error(str(e)) + exit(1) + try: asyncio.run(pferd.run()) except KeyboardInterrupt: diff --git a/PFERD/pferd.py b/PFERD/pferd.py index 10cd1c2..20c770f 100644 --- a/PFERD/pferd.py +++ b/PFERD/pferd.py @@ -1,71 +1,58 @@ from typing import Dict -from rich import print from rich.markup import escape from .authenticator import Authenticator from .authenticators import AUTHENTICATORS -from .config import Config -from .crawler import Crawler +from .config import Config, ConfigOptionError +from .crawler import Crawler, CrawlError from .crawlers import CRAWLERS - - -class PferdLoadException(Exception): - pass +from .logging import log class Pferd: def __init__(self, config: Config): + """ + May throw ConfigOptionError. + """ + self._config = config self._authenticators: Dict[str, Authenticator] = {} self._crawlers: Dict[str, Crawler] = {} + self._load_authenticators() + self._load_crawlers() + def _load_authenticators(self) -> None: - abort = False for name, section in self._config.authenticator_sections(): - print(f"[bold bright_cyan]Loading[/] {escape(name)}") - authenticator_type = section.get("type") - authenticator_constructor = AUTHENTICATORS.get(authenticator_type) + log.print(f"[bold bright_cyan]Loading[/] {escape(name)}") + auth_type = section.get("type") + authenticator_constructor = AUTHENTICATORS.get(auth_type) if authenticator_constructor is None: - abort = True - t = escape(repr(authenticator_type)) - print(f"[red]Error: Unknown authenticator type {t}") - continue + raise ConfigOptionError(name, "type", f"Unknown authenticator type: {auth_type!r}") authenticator = authenticator_constructor(name, section, self._config) self._authenticators[name] = authenticator - if abort: - raise PferdLoadException() - def _load_crawlers(self) -> None: - abort = False for name, section in self._config.crawler_sections(): - print(f"[bold bright_cyan]Loading[/] {escape(name)}") - crawler_type = section.get("type") - crawler_constructor = CRAWLERS.get(crawler_type) + log.print(f"[bold bright_cyan]Loading[/] {escape(name)}") + crawl_type = section.get("type") + crawler_constructor = CRAWLERS.get(crawl_type) if crawler_constructor is None: - abort = True - t = escape(repr(crawler_type)) - print(f"[red]Error: Unknown crawler type {t}") - continue + raise ConfigOptionError(name, "type", f"Unknown crawler type: {crawl_type!r}") crawler = crawler_constructor(name, section, self._config, self._authenticators) self._crawlers[name] = crawler - if abort: - raise PferdLoadException() - async def run(self) -> None: - try: - self._load_authenticators() - self._load_crawlers() - except PferdLoadException: - print("[bold red]Could not initialize PFERD properly") - exit(1) - for name, crawler in self._crawlers.items(): - print() - print(f"[bold bright_cyan]Running[/] {escape(name)}") + log.print("") + log.print(f"[bold bright_cyan]Running[/] {escape(name)}") - await crawler.run() + try: + await crawler.run() + except CrawlError as e: + log.error(str(e)) + except Exception: + log.unexpected_exception()