- Gate server requests on available credentials - Run local child agents directly without a parent run ID - Include command IDs in Bedrock context and recognize transfer tools
117 lines
3.6 KiB
Rust
117 lines
3.6 KiB
Rust
mod anyhow;
|
|
mod registration;
|
|
mod reqwest;
|
|
#[cfg(not(target_family = "wasm"))]
|
|
mod tokio;
|
|
#[cfg(not(target_family = "wasm"))]
|
|
mod websocket;
|
|
|
|
// Re-export for macro use.
|
|
#[doc(hidden)]
|
|
pub use inventory::submit;
|
|
pub use registration::{register_error, ErrorRegistration, RegisteredError};
|
|
|
|
pub use self::anyhow::AnyhowErrorExt;
|
|
|
|
/// The `target` that is set by log entries from this module.
|
|
pub const LOG_TARGET: &str = "errors::report_error";
|
|
|
|
/// Controls how often a [`report_error!`] invocation logs errors.
|
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
pub enum ReportErrorLogMode {
|
|
/// Log every time the error is reported.
|
|
#[default]
|
|
EveryTime,
|
|
/// Log only the first time this macro invocation is reached during the
|
|
/// current app run.
|
|
OncePerRun,
|
|
}
|
|
|
|
/// Reports an error encountered during execution.
|
|
///
|
|
/// This checks whether or not the error is actionable, and logs an error or
|
|
/// warning accordingly. (Logs at the Error level get reported back to us, so
|
|
/// we don't want to log anything at Error level that we aren't able to act
|
|
/// upon.)
|
|
#[macro_export]
|
|
macro_rules! report_error {
|
|
(@log $err:expr) => {{
|
|
#[allow(unused_imports)]
|
|
use $crate::errors::{AnyhowErrorExt as _, ErrorExt as _, LOG_TARGET};
|
|
let err = $err;
|
|
let log_level = if err.is_actionable() {
|
|
err.report_error();
|
|
log::Level::Error
|
|
} else {
|
|
log::Level::Warn
|
|
};
|
|
log::log!(target: LOG_TARGET, log_level, "{:#}", err);
|
|
}};
|
|
(@once_per_run $err:expr) => {{
|
|
static HAS_LOGGED_REPORT_ERROR: ::std::sync::atomic::AtomicBool =
|
|
::std::sync::atomic::AtomicBool::new(false);
|
|
if !HAS_LOGGED_REPORT_ERROR.swap(true, ::std::sync::atomic::Ordering::Relaxed) {
|
|
$crate::report_error!(@log $err);
|
|
}
|
|
}};
|
|
($err:expr) => {{
|
|
$crate::report_error!(@log $err);
|
|
}};
|
|
($err:expr, $crate::errors::ReportErrorLogMode::EveryTime) => {{
|
|
$crate::report_error!(@log $err);
|
|
}};
|
|
($err:expr, ReportErrorLogMode::EveryTime) => {{
|
|
$crate::report_error!(@log $err);
|
|
}};
|
|
($err:expr, $crate::errors::ReportErrorLogMode::OncePerRun) => {{
|
|
$crate::report_error!(@once_per_run $err);
|
|
}};
|
|
($err:expr, ReportErrorLogMode::OncePerRun) => {{
|
|
$crate::report_error!(@once_per_run $err);
|
|
}};
|
|
($err:expr, $log_mode:expr) => {{
|
|
match $log_mode {
|
|
$crate::errors::ReportErrorLogMode::EveryTime => {
|
|
$crate::report_error!(@log $err);
|
|
}
|
|
$crate::errors::ReportErrorLogMode::OncePerRun => {
|
|
$crate::report_error!(@once_per_run $err);
|
|
}
|
|
}
|
|
}};
|
|
}
|
|
pub use report_error;
|
|
|
|
/// Reports an error if the provided [`Result`] is [`Err`].
|
|
///
|
|
/// This checks whether or not the error is actionable, and logs an error or
|
|
/// warning accordingly. (Logs at the Error level get reported back to us, so
|
|
/// we don't want to log anything at Error level that we aren't able to act
|
|
/// upon.)
|
|
#[macro_export]
|
|
macro_rules! report_if_error {
|
|
($result:expr) => {{
|
|
if let Err(error) = &$result {
|
|
$crate::report_error!(error);
|
|
}
|
|
}};
|
|
($result:expr, $log_mode:expr) => {{
|
|
if let Err(error) = &$result {
|
|
$crate::report_error!(error, $log_mode);
|
|
}
|
|
}};
|
|
}
|
|
pub use report_if_error;
|
|
|
|
pub trait ErrorExt: RegisteredError + std::error::Error {
|
|
/// Returns whether or not an error is something that is actionable by our
|
|
/// engineering team.
|
|
fn is_actionable(&self) -> bool;
|
|
|
|
fn report_error(&self) {}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[path = "errors_tests.rs"]
|
|
mod tests;
|