From 6909c20e69f08d256360dd29e50eacd02f49dfb8 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 12 Sep 2020 16:57:14 +0300 Subject: Exit with status 2 for recoverable errors --- bpkg/bpkg.cli | 15 ++++++++++++++- bpkg/bpkg.cxx | 7 +++++++ bpkg/diagnostics.hxx | 5 +++++ bpkg/rep-fetch.cxx | 35 ++++++++++++++++++++++------------- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/bpkg/bpkg.cli b/bpkg/bpkg.cli index b1c0a00..4975db7 100644 --- a/bpkg/bpkg.cli +++ b/bpkg/bpkg.cli @@ -322,6 +322,19 @@ namespace bpkg "\h|EXIT STATUS| - Non-zero exit status is returned in case of an error. + \dl| + + \li|\cb{0} + + Success.| + + \li|\cb{1} + + Fatal error.| + + \li|\cb{2} + + Recoverable error which is likely to disappear if the command is + re-executed.|| " } diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx index ffc91ab..7aba553 100644 --- a/bpkg/bpkg.cxx +++ b/bpkg/bpkg.cxx @@ -517,6 +517,13 @@ try assert (false); fail << "unhandled command"; } + // Derived from failed and so needs to be caught first. + // + catch (const recoverable&) + { + r = 2; + break; + } catch (const failed&) { r = 1; diff --git a/bpkg/diagnostics.hxx b/bpkg/diagnostics.hxx index d11ab0b..925b080 100644 --- a/bpkg/diagnostics.hxx +++ b/bpkg/diagnostics.hxx @@ -21,6 +21,11 @@ namespace bpkg // class failed: public std::exception {}; + // As above but needs to be used for recoverable errors which are likely to + // disappear on the command retry. + // + class recoverable: public failed {}; + // Print process commmand line. If the number of elements is specified // (or the second version is used), then it will print the piped multi- // process command line, if present. In this case, the expected format diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx index b58ef2c..3239421 100644 --- a/bpkg/rep-fetch.cxx +++ b/bpkg/rep-fetch.cxx @@ -85,10 +85,14 @@ namespace bpkg pkg_package_manifests& pms (pmc.first); if (rmc.second != pms.sha256sum) - fail << "repositories manifest file checksum mismatch for " - << rl.canonical_name () << + { + error << "repositories manifest file checksum mismatch for " + << rl.canonical_name () << info << "try again"; + throw recoverable (); + } + fr.packages = move (pms); if (a) @@ -97,10 +101,14 @@ namespace bpkg pkg_fetch_signature (co, rl, true /* ignore_unknown */)); if (sm.sha256sum != pmc.second) - fail << "packages manifest file checksum mismatch for " - << rl.canonical_name () << + { + error << "packages manifest file checksum mismatch for " + << rl.canonical_name () << info << "try again"; + throw recoverable (); + } + assert (cert != nullptr); authenticate_repository (co, conf, cert_pem, *cert, sm, rl); } @@ -911,12 +919,12 @@ namespace bpkg info << r1 << " has " << *pm.sha256sum << info << r2 << " has " << *p->sha256sum; - // If we fetch all the repositories then the mismatch is definitely - // caused by the broken repository. Otherwise, it may also happen - // due to the old available package that is not wiped out yet. - // Thus, we advice the user to perform the full fetch, unless the - // filesystem state is already changed and so this advice will be - // given anyway (see rep_fetch() for details). + // If we fetch all the repositories then the mismatch is + // definitely caused by the broken repository. Otherwise, it may + // also happen due to the old available package that is not wiped + // out yet. Thus, we advice the user to perform the full fetch, + // unless the filesystem state is already changed and so this + // advice will be given anyway (see rep_fetch() for details). // if (full_fetch) dr << info << "consider reporting this to the repository " @@ -969,15 +977,16 @@ namespace bpkg // otherwise. // // Note that we can end up with a repository dependency cycle via - // prerequisites. Thus we register the repository before recursing into its - // dependencies. + // prerequisites. Thus we register the repository before recursing into + // its dependencies. // if (!fetched_repositories.insert (r).second) // Is already fetched. { // Authenticate the repository use by the dependent, if required. // // Note that we only need to authenticate the certificate but not the - // repository that was already fetched (and so is already authenticated). + // repository that was already fetched (and so is already + // authenticated). // if (need_auth (co, r->location)) authenticate_certificate (co, -- cgit v1.1