From 9d3e4b9cd4dbe973b48aa7a774240edcea4bd1e2 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Fri, 1 Nov 2024 14:57:59 -0400 Subject: [PATCH 1/2] do not show full traceback by default Change the behavior of the main program to show only the summary of an exception and not the full traceback, by default. Add a `--debug` flag to expose the traceback information for debugging, if needed. --- src/fromager/__main__.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/fromager/__main__.py b/src/fromager/__main__.py index c92af2d8..d545793b 100644 --- a/src/fromager/__main__.py +++ b/src/fromager/__main__.py @@ -18,6 +18,7 @@ TERSE_LOG_FMT = "%(message)s" VERBOSE_LOG_FMT = "%(levelname)s:%(name)s:%(lineno)d: %(message)s" +_DEBUG = False try: external_commands.detect_network_isolation() @@ -37,6 +38,12 @@ is_flag=True, help="report more detail to the console", ) +@click.option( + "--debug", + default=False, + is_flag=True, + help="report full tracebacks to the console", +) @click.option( "--log-file", type=clickext.ClickPath(), @@ -131,6 +138,7 @@ def main( ctx: click.Context, verbose: bool, + debug: bool, log_file: pathlib.Path, error_log_file: pathlib.Path, sdists_repo: pathlib.Path, @@ -146,6 +154,10 @@ def main( jobs: int | None, network_isolation: bool, ) -> None: + # Save the debug flag so invoke_main() can use it. + global _DEBUG + _DEBUG = debug + # Set the overall logger level to debug and allow the handlers to filter # messages at their own level. logging.getLogger().setLevel(logging.DEBUG) @@ -226,8 +238,13 @@ def invoke_main() -> None: try: main(auto_envvar_prefix="FROMAGER") except Exception as err: - logger.exception(err) - raise + logger.debug( + err, + exc_info=True, + ) # log the full traceback details to the debug log file, if any + logger.error(f"ERROR: {err}") + if _DEBUG: + raise if __name__ == "__main__": From 14c4f9122ce3d6025c0eafabdcc8a490c7816343 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Fri, 1 Nov 2024 14:58:58 -0400 Subject: [PATCH 2/2] improve the formatting of resolution errors Use ValueError exceptions to provide a nicer message for the resolver when it fails. --- src/fromager/resolver.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fromager/resolver.py b/src/fromager/resolver.py index bab57028..8a39f1e9 100644 --- a/src/fromager/resolver.py +++ b/src/fromager/resolver.py @@ -93,7 +93,10 @@ def resolve_from_provider( ) -> tuple[str, Version]: reporter: resolvelib.BaseReporter = resolvelib.BaseReporter() rslvr: resolvelib.Resolver = resolvelib.Resolver(provider, reporter) - result = rslvr.resolve([req]) + try: + result = rslvr.resolve([req]) + except resolvelib.resolvers.exceptions.ResolutionImpossible as err: + raise ValueError(f"Unable to resolve {req}") from err # resolvelib actually just returns one candidate per requirement. # result.mapping is map from an identifier to its resolved candidate candidate: Candidate