rust: Add and use fn-error-context
Same motivation as https://github.com/coreos/bootupd/pull/163 Effectively what we're doing here is creating a human-readable subset of the stack trace. This is nicer than having the calling functions add with_context() because it's more verbose (gets duplicative at each call site), easy to forget, etc.
This commit is contained in:
parent
1dc7503838
commit
95ff12b913
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -324,6 +324,17 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fn-error-context"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac0b92c51c8b8183a0c101a7b2ea5fac11d2f1e01057f91e390284c75d76ef44"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1203,6 +1214,7 @@ dependencies = [
|
|||||||
"curl",
|
"curl",
|
||||||
"cxx",
|
"cxx",
|
||||||
"envsubst",
|
"envsubst",
|
||||||
|
"fn-error-context",
|
||||||
"gio",
|
"gio",
|
||||||
"gio-sys",
|
"gio-sys",
|
||||||
"glib",
|
"glib",
|
||||||
|
@ -32,6 +32,7 @@ clap = "2.33.3"
|
|||||||
curl = "0.4.34"
|
curl = "0.4.34"
|
||||||
cxx = "1.0.32"
|
cxx = "1.0.32"
|
||||||
envsubst = "0.2.0"
|
envsubst = "0.2.0"
|
||||||
|
fn-error-context = "0.1.1"
|
||||||
gio = "0.9.1"
|
gio = "0.9.1"
|
||||||
gio-sys = "0.10.1"
|
gio-sys = "0.10.1"
|
||||||
gobject-sys = "0.10.0"
|
gobject-sys = "0.10.0"
|
||||||
|
@ -161,18 +161,21 @@ mod err {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use fn_error_context::context;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn throwchain() {
|
fn throwchain() {
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
fn outer() -> CxxResult<()> {
|
fn outer() -> CxxResult<()> {
|
||||||
|
#[context("inner")]
|
||||||
fn inner() -> anyhow::Result<()> {
|
fn inner() -> anyhow::Result<()> {
|
||||||
anyhow::bail!("inner")
|
anyhow::bail!("oops")
|
||||||
}
|
}
|
||||||
Ok(inner().context("Failed in outer")?)
|
Ok(inner().context("Failed in outer")?)
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{}", outer().err().unwrap()),
|
format!("{}", outer().err().unwrap()),
|
||||||
"Failed in outer: inner"
|
"Failed in outer: inner: oops"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
//! Compute difference between two filesystem trees.
|
//! Compute difference between two filesystem trees.
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::Result;
|
||||||
|
use fn_error_context::context;
|
||||||
use openat_ext::OpenatDirExt;
|
use openat_ext::OpenatDirExt;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
@ -204,11 +205,12 @@ fn diff_recurse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Given two directories, compute the diff between them.
|
/// Given two directories, compute the diff between them.
|
||||||
|
#[context("Computing filesystem diff")]
|
||||||
pub(crate) fn diff(src: &openat::Dir, dest: &openat::Dir) -> Result<Diff> {
|
pub(crate) fn diff(src: &openat::Dir, dest: &openat::Dir) -> Result<Diff> {
|
||||||
let mut diff = Diff {
|
let mut diff = Diff {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
diff_recurse(None, src, dest, &mut diff).context("Failed to compute fsdiff")?;
|
diff_recurse(None, src, dest, &mut diff)?;
|
||||||
Ok(diff)
|
Ok(diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
// (FIXME: Convert to Apache-2.0 OR MIT for consistency?)
|
// (FIXME: Convert to Apache-2.0 OR MIT for consistency?)
|
||||||
use crate::cxxrsutil::*;
|
use crate::cxxrsutil::*;
|
||||||
use crate::ffi::HistoryEntry;
|
use crate::ffi::HistoryEntry;
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use fn_error_context::context;
|
||||||
use openat::{self, Dir, SimpleType};
|
use openat::{self, Dir, SimpleType};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -176,6 +177,7 @@ fn history_get_oldest_deployment_msg_timestamp() -> Result<Option<u64>> {
|
|||||||
/// Gets the oldest deployment message in the journal, and nuke all the GVariant data files
|
/// Gets the oldest deployment message in the journal, and nuke all the GVariant data files
|
||||||
/// that correspond to deployments older than that one. Essentially, this binds pruning to
|
/// that correspond to deployments older than that one. Essentially, this binds pruning to
|
||||||
/// journal pruning.
|
/// journal pruning.
|
||||||
|
#[context("Failed to prune history")]
|
||||||
fn history_prune_inner() -> Result<()> {
|
fn history_prune_inner() -> Result<()> {
|
||||||
if !Path::new(RPMOSTREE_HISTORY_DIR).exists() {
|
if !Path::new(RPMOSTREE_HISTORY_DIR).exists() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -211,7 +213,7 @@ fn history_prune_inner() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn history_prune() -> CxxResult<()> {
|
pub(crate) fn history_prune() -> CxxResult<()> {
|
||||||
Ok(history_prune_inner().context("Failed to prune history")?)
|
Ok(history_prune_inner()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn history_ctx_new() -> CxxResult<Box<HistoryCtx>> {
|
pub(crate) fn history_ctx_new() -> CxxResult<Box<HistoryCtx>> {
|
||||||
|
@ -439,8 +439,7 @@ pub(crate) fn transaction_apply_live(
|
|||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
.unwrap_or(booted_commit);
|
.unwrap_or(booted_commit);
|
||||||
// Compute the filesystem-level diff
|
// Compute the filesystem-level diff
|
||||||
let diff = crate::ostree_diff::diff(repo, source_commit, &target_commit, Some("/usr"))
|
let diff = crate::ostree_diff::diff(repo, source_commit, &target_commit, Some("/usr"))?;
|
||||||
.context("Failed computing diff")?;
|
|
||||||
// And then the package-level diff
|
// And then the package-level diff
|
||||||
let pkgdiff = {
|
let pkgdiff = {
|
||||||
cxx::let_cxx_string!(from = source_commit);
|
cxx::let_cxx_string!(from = source_commit);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use fn_error_context::context;
|
||||||
use gio::prelude::*;
|
use gio::prelude::*;
|
||||||
use ostree::RepoFileExt;
|
use ostree::RepoFileExt;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
@ -149,6 +150,7 @@ fn diff_recurse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Given two ostree commits, compute the diff between them.
|
/// Given two ostree commits, compute the diff between them.
|
||||||
|
#[context("Computing ostree diff")]
|
||||||
pub(crate) fn diff<P: AsRef<str>>(
|
pub(crate) fn diff<P: AsRef<str>>(
|
||||||
repo: &ostree::Repo,
|
repo: &ostree::Repo,
|
||||||
from: &str,
|
from: &str,
|
||||||
|
Loading…
Reference in New Issue
Block a user