Standardize logging and error handling

- Introduce new types: LoggedResult and LoggedError
- Introduce new extension methods to log and add additional msgs
- Never exit when logging error messages in Rust (all errors should be
  handled by using Result and Rust's error propagation)
- Remove all usages of anyhow as it doesn't fit Magisk's use cases
This commit is contained in:
topjohnwu
2023-06-29 16:44:44 -07:00
parent dbc2236dd2
commit 4ee4cbada6
16 changed files with 254 additions and 145 deletions
+22 -21
View File
@@ -1,13 +1,13 @@
use std::fmt::Write as FmtWrite;
use std::fs::File;
use std::io::{BufReader, Read, Seek, SeekFrom, Write};
use std::os::fd::{AsRawFd, FromRawFd};
use anyhow::{anyhow, Context};
use byteorder::{BigEndian, ReadBytesExt};
use quick_protobuf::{BytesReader, MessageRead};
use base::libc::c_char;
use base::{ReadSeekExt, StrErr, Utf8CStr};
use base::{error, LoggedError, LoggedResult, ReadSeekExt, StrErr, Utf8CStr};
use base::{ResultExt, WriteExt};
use crate::ffi;
@@ -15,12 +15,14 @@ use crate::proto::update_metadata::mod_InstallOperation::Type;
use crate::proto::update_metadata::DeltaArchiveManifest;
macro_rules! bad_payload {
($msg:literal) => {
anyhow!(concat!("invalid payload: ", $msg))
};
($($args:tt)*) => {
anyhow!("invalid payload: {}", format_args!($($args)*))
};
($msg:literal) => {{
error!(concat!("Invalid payload: ", $msg));
LoggedError::default()
}};
($($args:tt)*) => {{
error!("Invalid payload: {}", format_args!($($args)*));
LoggedError::default()
}};
}
const PAYLOAD_MAGIC: &str = "CrAU";
@@ -29,11 +31,11 @@ fn do_extract_boot_from_payload(
in_path: &Utf8CStr,
partition_name: Option<&Utf8CStr>,
out_path: Option<&Utf8CStr>,
) -> anyhow::Result<()> {
) -> LoggedResult<()> {
let mut reader = BufReader::new(if in_path == "-" {
unsafe { File::from_raw_fd(0) }
} else {
File::open(in_path).with_context(|| format!("cannot open '{in_path}'"))?
File::open(in_path).log_with_msg(|w| write!(w, "Cannot open '{}'", in_path))?
});
let buf = &mut [0u8; 4];
@@ -88,13 +90,13 @@ fn do_extract_boot_from_payload(
.iter()
.find(|p| p.partition_name == "boot"),
};
boot.ok_or(anyhow!("boot partition not found"))?
boot.ok_or_else(|| bad_payload!("boot partition not found"))?
}
Some(name) => manifest
.partitions
.iter()
.find(|p| p.partition_name.as_str() == name)
.ok_or(anyhow!("partition '{name}' not found"))?,
.ok_or_else(|| bad_payload!("partition '{}' not found", name))?,
};
let out_str: String;
@@ -107,7 +109,7 @@ fn do_extract_boot_from_payload(
};
let mut out_file =
File::create(out_path).with_context(|| format!("cannot write to '{out_path}'"))?;
File::create(out_path).log_with_msg(|w| write!(w, "Cannot write to '{}'", out_path))?;
// Skip the manifest signature
reader.skip(manifest_sig_len as usize)?;
@@ -121,11 +123,11 @@ fn do_extract_boot_from_payload(
for operation in operations.iter() {
let data_len = operation
.data_length
.ok_or(bad_payload!("data length not found"))? as usize;
.ok_or_else(|| bad_payload!("data length not found"))? as usize;
let data_offset = operation
.data_offset
.ok_or(bad_payload!("data offset not found"))?;
.ok_or_else(|| bad_payload!("data offset not found"))?;
let data_type = operation.type_pb;
@@ -141,9 +143,9 @@ fn do_extract_boot_from_payload(
let out_offset = operation
.dst_extents
.get(0)
.ok_or(bad_payload!("dst extents not found"))?
.ok_or_else(|| bad_payload!("dst extents not found"))?
.start_block
.ok_or(bad_payload!("start block not found"))?
.ok_or_else(|| bad_payload!("start block not found"))?
* block_size;
match data_type {
@@ -184,7 +186,7 @@ pub fn extract_boot_from_payload(
in_path: *const c_char,
partition: *const c_char,
out_path: *const c_char,
) -> anyhow::Result<()> {
) -> LoggedResult<()> {
let in_path = unsafe { Utf8CStr::from_ptr(in_path) }?;
let partition = match unsafe { Utf8CStr::from_ptr(partition) } {
Ok(s) => Some(s),
@@ -197,8 +199,7 @@ pub fn extract_boot_from_payload(
Err(e) => Err(e)?,
};
do_extract_boot_from_payload(in_path, partition, out_path)
.context("Failed to extract from payload")?;
Ok(())
.log_with_msg(|w| w.write_str("Failed to extract from payload"))
}
inner(in_path, partition, out_path).log().is_ok()
inner(in_path, partition, out_path).is_ok()
}