cli: promote WithHint hint type to String
Changes the `Error::WithHint::hint` field to use a `String` type instead of `&'static str`. This allows the caller to provide extra hint information. To make it easier to use an `Error::with_hint` constructor is added.
This commit is contained in:
parent
67a4a712e4
commit
60959f7e83
|
|
@ -136,11 +136,10 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
Ok(proposal) => proposal,
|
Ok(proposal) => proposal,
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
update::error::PrivacyAllowList::Overlapping(overlap) =>anyhow::bail!("`--allow` and `--disallow` must not overlap: {overlap:?}"),
|
update::error::PrivacyAllowList::Overlapping(overlap) =>anyhow::bail!("`--allow` and `--disallow` must not overlap: {overlap:?}"),
|
||||||
update::error::PrivacyAllowList::PublicVisibility => return Err(Error::WithHint {
|
update::error::PrivacyAllowList::PublicVisibility => return Err(Error::with_hint(
|
||||||
err:
|
|
||||||
anyhow!("`--allow` and `--disallow` should only be used for private repositories"),
|
anyhow!("`--allow` and `--disallow` should only be used for private repositories"),
|
||||||
hint: "use `--visibility private` to make the repository private, or perhaps you meant to use `--delegate`/`--rescind`",
|
"use `--visibility private` to make the repository private, or perhaps you meant to use `--delegate`/`--rescind`")
|
||||||
}.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let threshold = proposal.threshold;
|
let threshold = proposal.threshold;
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,8 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
let id = id.resolve(&repo.backend)?;
|
let id = id.resolve(&repo.backend)?;
|
||||||
let issue = issues
|
let issue = issues
|
||||||
.get(&id)
|
.get(&id)
|
||||||
.map_err(|e| Error::WithHint {
|
.map_err(|e| {
|
||||||
err: e.into(),
|
Error::with_hint(e, "reset the cache with `rad issue cache` and try again")
|
||||||
hint: "reset the cache with `rad issue cache` and try again",
|
|
||||||
})?
|
})?
|
||||||
.context("No issue with the given ID exists")?;
|
.context("No issue with the given ID exists")?;
|
||||||
term::issue::show(&issue, &id, format, args.verbose, &profile)?;
|
term::issue::show(&issue, &id, format, args.verbose, &profile)?;
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,9 @@ pub fn run(
|
||||||
workdir: Option<&git::raw::Repository>,
|
workdir: Option<&git::raw::Repository>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let patches = term::cob::patches(profile, stored)?;
|
let patches = term::cob::patches(profile, stored)?;
|
||||||
let Some(patch) = patches.get(patch_id).map_err(|e| Error::WithHint {
|
let Some(patch) = patches
|
||||||
err: e.into(),
|
.get(patch_id)
|
||||||
hint: "reset the cache with `rad patch cache` and try again",
|
.map_err(|e| Error::with_hint(e, "reset the cache with `rad patch cache` and try again"))?
|
||||||
})?
|
|
||||||
else {
|
else {
|
||||||
anyhow::bail!("Patch `{patch_id}` not found");
|
anyhow::bail!("Patch `{patch_id}` not found");
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,20 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
let doc = identity.doc();
|
let doc = identity.doc();
|
||||||
|
|
||||||
if doc.is_public() {
|
if doc.is_public() {
|
||||||
return Err(term::Error::WithHint {
|
return Err(term::Error::with_hint(
|
||||||
err: anyhow!("repository is already public"),
|
anyhow!("repository is already public"),
|
||||||
hint: "to announce the repository to the network, run `rad sync --inventory`",
|
"to announce the repository to the network, run `rad sync --inventory`",
|
||||||
}
|
)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
if !doc.is_delegate(&profile.id().into()) {
|
if !doc.is_delegate(&profile.id().into()) {
|
||||||
return Err(anyhow!("only the repository delegate can publish it"));
|
return Err(anyhow!("only the repository delegate can publish it"));
|
||||||
}
|
}
|
||||||
if doc.delegates().len() > 1 {
|
if doc.delegates().len() > 1 {
|
||||||
return Err(term::Error::WithHint {
|
return Err(term::Error::with_hint(
|
||||||
err: anyhow!(
|
anyhow!("only repositories with a single delegate can be published with this command"),
|
||||||
"only repositories with a single delegate can be published with this command"
|
"see `rad id --help` to publish repositories with more than one delegate",
|
||||||
),
|
)
|
||||||
hint: "see `rad id --help` to publish repositories with more than one delegate",
|
|
||||||
}
|
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
let signer = profile.signer()?;
|
let signer = profile.signer()?;
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,10 @@ impl Context for DefaultContext {
|
||||||
fn profile(&self) -> Result<Profile, anyhow::Error> {
|
fn profile(&self) -> Result<Profile, anyhow::Error> {
|
||||||
match Profile::load() {
|
match Profile::load() {
|
||||||
Ok(profile) => Ok(profile),
|
Ok(profile) => Ok(profile),
|
||||||
Err(radicle::profile::Error::NotFound(path)) => Err(args::Error::WithHint {
|
Err(radicle::profile::Error::NotFound(path)) => Err(args::Error::with_hint(
|
||||||
err: anyhow::anyhow!("Radicle profile not found in '{}'.", path.display()),
|
anyhow::anyhow!("Radicle profile not found in '{}'.", path.display()),
|
||||||
hint: "To setup your radicle profile, run `rad auth`.",
|
"To setup your radicle profile, run `rad auth`.",
|
||||||
}
|
)
|
||||||
.into()),
|
.into()),
|
||||||
Err(radicle::profile::Error::LoadConfig(e)) => Err(e.into()),
|
Err(radicle::profile::Error::LoadConfig(e)) => Err(e.into()),
|
||||||
Err(e) => Err(anyhow::anyhow!("Could not load radicle profile: {e}")),
|
Err(e) => Err(anyhow::anyhow!("Could not load radicle profile: {e}")),
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,20 @@ use radicle::prelude::{Did, NodeId, RepoId};
|
||||||
pub(crate) enum Error {
|
pub(crate) enum Error {
|
||||||
/// An error with a hint.
|
/// An error with a hint.
|
||||||
#[error("{err}")]
|
#[error("{err}")]
|
||||||
WithHint {
|
WithHint { err: anyhow::Error, hint: String },
|
||||||
err: anyhow::Error,
|
}
|
||||||
hint: &'static str,
|
|
||||||
},
|
impl Error {
|
||||||
|
pub fn with_hint<E, H>(err: E, hint: H) -> Self
|
||||||
|
where
|
||||||
|
E: Into<anyhow::Error>,
|
||||||
|
H: ToString,
|
||||||
|
{
|
||||||
|
Self::WithHint {
|
||||||
|
err: err.into(),
|
||||||
|
hint: hint.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Targets used in the `block` and `unblock` commands
|
/// Targets used in the `block` and `unblock` commands
|
||||||
|
|
|
||||||
|
|
@ -108,10 +108,7 @@ fn with_hint(e: profile::Error) -> anyhow::Error {
|
||||||
#[allow(clippy::wildcard_enum_match_arm)]
|
#[allow(clippy::wildcard_enum_match_arm)]
|
||||||
match e {
|
match e {
|
||||||
profile::Error::CobsCache(cob::cache::Error::OutOfDate) => {
|
profile::Error::CobsCache(cob::cache::Error::OutOfDate) => {
|
||||||
anyhow::Error::from(terminal::args::Error::WithHint {
|
terminal::args::Error::with_hint(e, MIGRATION_HINT).into()
|
||||||
err: e.into(),
|
|
||||||
hint: MIGRATION_HINT,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
e => anyhow::Error::from(e),
|
e => anyhow::Error::from(e),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue