aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-09-12 16:57:14 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-09-14 16:27:11 +0300
commit6909c20e69f08d256360dd29e50eacd02f49dfb8 (patch)
tree16f14b482632ad52333a8e598d6e021bd1c442ec
parentc289f73d6fdc9f86b90e0986ba3b0da0c29e7927 (diff)
Exit with status 2 for recoverable errors
-rw-r--r--bpkg/bpkg.cli15
-rw-r--r--bpkg/bpkg.cxx7
-rw-r--r--bpkg/diagnostics.hxx5
-rw-r--r--bpkg/rep-fetch.cxx35
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,