diff --git a/spdlog/benches/spdlog-rs/compare_with_cpp_spdlog_async.rs b/spdlog/benches/spdlog-rs/compare_with_cpp_spdlog_async.rs index ff09257b..0ef47bd1 100644 --- a/spdlog/benches/spdlog-rs/compare_with_cpp_spdlog_async.rs +++ b/spdlog/benches/spdlog-rs/compare_with_cpp_spdlog_async.rs @@ -13,7 +13,7 @@ use spdlog::{ formatter::{pattern, PatternFormatter}, prelude::*, sink::*, - ThreadPool, + ErrorHandler, ThreadPool, }; use test::black_box; @@ -46,7 +46,7 @@ fn bench( .thread_pool(thread_pool) .overflow_policy(policy) .sink(file_sink) - .error_handler(|err| panic!("an error occurred: {err}")) + .error_handler(ErrorHandler::new(|err| panic!("an error occurred: {err}"))) .build() .unwrap(), ); @@ -54,13 +54,13 @@ fn bench( let logger = Logger::builder() .sink(async_sink) .name("async_logger") - .error_handler(|err| { + .error_handler(ErrorHandler::new(|err| { if let Error::SendToChannel(SendToChannelError::Full, _dropped_data) = err { // ignore } else { panic!("an error occurred: {err}") } - }) + })) .build() .unwrap(); diff --git a/spdlog/benches/spdlog-rs/log_crate_proxy.rs b/spdlog/benches/spdlog-rs/log_crate_proxy.rs index 67222b52..6ebd34dd 100644 --- a/spdlog/benches/spdlog-rs/log_crate_proxy.rs +++ b/spdlog/benches/spdlog-rs/log_crate_proxy.rs @@ -18,7 +18,9 @@ use test_utils::*; fn init() { if spdlog::init_log_crate_proxy().is_ok() { spdlog::set_default_logger(Arc::new(build_test_logger(|b| { - b.error_handler(|err| panic!("an error occurred: {err}")) + b.error_handler(spdlog::ErrorHandler::new(|err| { + panic!("an error occurred: {err}") + })) }))); } log::set_max_level(log::LevelFilter::max()); diff --git a/spdlog/benches/spdlog-rs/pattern.rs b/spdlog/benches/spdlog-rs/pattern.rs index 47db21f9..46b4f7ec 100644 --- a/spdlog/benches/spdlog-rs/pattern.rs +++ b/spdlog/benches/spdlog-rs/pattern.rs @@ -68,7 +68,7 @@ impl Sink for BenchSink<'_, F> { unimplemented!() } - fn set_error_handler(&self, _handler: Option) { + fn set_error_handler(&self, _handler: spdlog::ErrorHandler) { unimplemented!() } } diff --git a/spdlog/benches/spdlog-rs/spdlog_rs.rs b/spdlog/benches/spdlog-rs/spdlog_rs.rs index 7fd74036..9d5d1da4 100644 --- a/spdlog/benches/spdlog-rs/spdlog_rs.rs +++ b/spdlog/benches/spdlog-rs/spdlog_rs.rs @@ -57,20 +57,20 @@ impl Mode { const PANIC_ERR: fn(Error) = |err| panic!("an error occurred: {err}"); match self { - Self::Sync => PANIC_ERR, - Self::Async => move |err| { + Self::Sync => ErrorHandler::new(PANIC_ERR), + Self::Async => ErrorHandler::new(move |err| { if let Error::SendToChannel(SendToChannelError::Full, _dropped_data) = err { // ignore } else { PANIC_ERR(err); } - }, + }), } } } fn bench_any(bencher: &mut Bencher, mode: Mode, sink: Arc) { - sink.set_error_handler(Some(|err| panic!("an error occurred: {err}"))); + sink.set_error_handler(ErrorHandler::new(|err| panic!("an error occurred: {err}"))); let logger = build_test_logger(|b| { b.error_handler(mode.error_handler()) diff --git a/spdlog/examples/04_format.rs b/spdlog/examples/04_format.rs index 220c7b8d..a029c396 100644 --- a/spdlog/examples/04_format.rs +++ b/spdlog/examples/04_format.rs @@ -52,11 +52,12 @@ fn impl_manually() { let style_range_begin = dest.len(); dest.write_str(&record.level().as_str().to_ascii_uppercase()) - .map_err(spdlog::Error::FormatRecord)?; + .map_err(|err| spdlog::Error::FormatRecord(err.into()))?; let style_range_end = dest.len(); - writeln!(dest, " {}", record.payload()).map_err(spdlog::Error::FormatRecord)?; + writeln!(dest, " {}", record.payload()) + .map_err(|err| spdlog::Error::FormatRecord(err.into()))?; ctx.set_style_range(Some(style_range_begin..style_range_end)); Ok(()) diff --git a/spdlog/examples/05_sink.rs b/spdlog/examples/05_sink.rs index a6b68f75..72c73516 100644 --- a/spdlog/examples/05_sink.rs +++ b/spdlog/examples/05_sink.rs @@ -12,7 +12,7 @@ use spin::{Mutex, RwLock}; struct CollectVecSink { level_filter: Atomic, formatter: RwLock>, - error_handler: Atomic>, + error_handler: Atomic, collected: Mutex>, } @@ -21,7 +21,7 @@ impl CollectVecSink { Self { level_filter: Atomic::new(LevelFilter::All), formatter: RwLock::new(Box::new(FullFormatter::new())), - error_handler: Atomic::new(None), + error_handler: Atomic::new(ErrorHandler::default()), collected: Mutex::new(Vec::new()), } } @@ -58,7 +58,7 @@ impl Sink for CollectVecSink { *self.formatter.write() = formatter; } - fn set_error_handler(&self, handler: Option) { + fn set_error_handler(&self, handler: ErrorHandler) { self.error_handler.store(handler, Ordering::Relaxed); } } diff --git a/spdlog/src/error.rs b/spdlog/src/error.rs index 1d54750b..1e9f5a54 100644 --- a/spdlog/src/error.rs +++ b/spdlog/src/error.rs @@ -1,11 +1,6 @@ //! Provides error types. -//! -//! # Default error handler -//! -//! If a logger or sink does not have an error handler set up, a default error -//! handler will be used, which will print the error to `stderr`. - use std::{ + error::Error as StdError, fmt::{self, Display}, io, result, }; @@ -18,6 +13,81 @@ use crate::utils::const_assert; #[cfg(feature = "multi-thread")] use crate::{sink::Task, RecordOwned}; +/// Stores an error that can either be typed or erased. +/// +/// This wrapper is mainly used for returning arbitrary errors from downstream +/// implementors. +/// +/// # Examples +/// +/// ``` +/// use std::{error::Error, fmt, io}; +/// +/// use spdlog::{error::ErasableError, formatter::Formatter, prelude::*, sink::Sink, Record}; +/// +/// #[derive(Debug)] +/// struct MyError; +/// +/// impl Error for MyError {} +/// +/// impl fmt::Display for MyError { +/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +/// write!(f, "MyError") +/// } +/// } +/// +/// struct MySink; +/// +/// impl Sink for MySink { +/// fn log(&self, record: &Record) -> spdlog::Result<()> { +/// let err: MyError = /* Something went wrong */ +/// # MyError; +/// // `err` can not be converted to `io::Error`, so we use `Erased` +/// Err(spdlog::Error::WriteRecord(ErasableError::erase(MyError))) +/// } +/// +/// fn flush(&self) -> spdlog::Result<()> { +/// let err: io::Error = /* Something went wrong */ +/// # io::Error::new(io::ErrorKind::NotFound, ""); +/// // `err` is a `io::Error`, so we use `Typed` +/// Err(spdlog::Error::FlushBuffer(err.into())) +/// } +/// +/// fn level_filter(&self) -> LevelFilter /* ... */ +/// # { unimplemented!() } +/// fn set_level_filter(&self, level_filter: LevelFilter) /* ... */ +/// # { unimplemented!() } +/// fn set_formatter(&self, formatter: Box) /* ... */ +/// # { unimplemented!() } +/// fn set_error_handler(&self, handler: spdlog::ErrorHandler) /* ... */ +/// # { unimplemented!() } +/// } +/// ``` +#[derive(Error, Debug)] +pub enum ErasableError { + /// A concrete error type is held, and the user can access it. + #[error("{0}")] + Typed(E), + /// The concrete type may not match, thus it is erased to a basic + /// `dyn std::error::Error`. + #[error("{0}")] + Erased(Box), +} + +impl ErasableError { + /// Erase a typed error to a basic `Box`. + #[must_use] + pub fn erase(err: R) -> ErasableError { + ErasableError::Erased(Box::new(err)) + } +} + +impl From for ErasableError { + fn from(err: E) -> Self { + Self::Typed(err) + } +} + /// Contains most errors of this crate. #[derive(Error, Debug)] #[non_exhaustive] @@ -26,20 +96,20 @@ pub enum Error { /// /// [`Formatter`]: crate::formatter::Formatter #[error("format record error: {0}")] - FormatRecord(fmt::Error), + FormatRecord(ErasableError), /// Returned by [`Sink`]s when an error occurs in writing a record to the /// target. /// /// [`Sink`]: crate::sink::Sink #[error("write record error: {0}")] - WriteRecord(io::Error), + WriteRecord(ErasableError), /// Returned by [`Sink`]s when an error occurs in flushing the buffer. /// /// [`Sink`]: crate::sink::Sink #[error("flush buffer error: {0}")] - FlushBuffer(io::Error), + FlushBuffer(ErasableError), /// Returned by [`Sink`]s when an error occurs in creating a directory. /// @@ -264,11 +334,86 @@ pub struct BuildPatternError(pub(crate) spdlog_internal::pattern_parser::Error); /// The result type of this crate. pub type Result = result::Result; -/// The error handler function type. -pub type ErrorHandler = fn(Error); +/// Represents an error handler. +/// +/// Call [`ErrorHandler::new`] to construct an error handler with a custom +/// function. +/// +/// Call [`ErrorHandler::default`] to construct an empty error handler, when an +/// error is triggered, a built-in fallback handler will be used which prints +/// the error to `stderr`. +#[derive(Copy, Clone, Debug)] +pub struct ErrorHandler(Option); const_assert!(Atomic::::is_lock_free()); -const_assert!(Atomic::>::is_lock_free()); + +impl ErrorHandler { + /// Constructs an error handler with a custom function. + #[must_use] + pub fn new(custom: fn(Error)) -> Self { + Self(Some(custom)) + } + + /// Sets the error handler. + /// + /// Passes `None` to use the built-in fallback handler, which prints errors + /// to `stderr`. + pub fn set(&mut self, handler: Option) { + self.0 = handler; + } + + /// Calls the error handler with an error. + pub fn call(&self, err: Error) { + self.call_internal("External", err); + } + + pub(crate) fn call_internal(&self, from: impl AsRef, err: Error) { + if let Some(handler) = self.0 { + handler(err); + } else { + Self::default_impl(from, err); + } + } + + fn default_impl(from: impl AsRef, error: Error) { + if let Error::Multiple(errs) = error { + errs.into_iter() + .for_each(|err| Self::default_impl(from.as_ref(), err)); + return; + } + + let date = chrono::Local::now() + .format("%Y-%m-%d %H:%M:%S.%3f") + .to_string(); + + eprintln!( + "[*** SPDLOG-RS UNHANDLED ERROR ***] [{}] [{}] {}", + date, + from.as_ref(), + error + ); + } +} + +impl Default for ErrorHandler { + /// Constructs an error handler with the built-in handler which prints + /// errors to `stderr`. + fn default() -> Self { + Self(None) + } +} + +// FIXME: Doesn't work as expected at the moment +// https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/impl.20From.3Cno-capture-closure.3E.20for.20fn.3F +// +// impl From for ErrorHandler +// where +// F: Into, +// { +// fn from(handler: F) -> Self { +// Self::new(handler.into()) +// } +// } #[cfg(test)] mod tests { diff --git a/spdlog/src/formatter/full_formatter.rs b/spdlog/src/formatter/full_formatter.rs index 11b6347f..75a6ca91 100644 --- a/spdlog/src/formatter/full_formatter.rs +++ b/spdlog/src/formatter/full_formatter.rs @@ -111,7 +111,7 @@ impl Formatter for FullFormatter { ctx: &mut FormatterContext, ) -> crate::Result<()> { self.format_impl(record, dest, ctx) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/journald_formatter.rs b/spdlog/src/formatter/journald_formatter.rs index 14ba53a4..83775daf 100644 --- a/spdlog/src/formatter/journald_formatter.rs +++ b/spdlog/src/formatter/journald_formatter.rs @@ -63,7 +63,7 @@ impl Formatter for JournaldFormatter { ctx: &mut FormatterContext, ) -> crate::Result<()> { self.format_impl(record, dest, ctx) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/json_formatter.rs b/spdlog/src/formatter/json_formatter.rs index dc3f6de0..d8755991 100644 --- a/spdlog/src/formatter/json_formatter.rs +++ b/spdlog/src/formatter/json_formatter.rs @@ -78,7 +78,7 @@ impl From for JsonFormatterError { impl From for crate::Error { fn from(value: JsonFormatterError) -> Self { match value { - JsonFormatterError::Fmt(e) => Error::FormatRecord(e), + JsonFormatterError::Fmt(e) => Error::FormatRecord(e.into()), JsonFormatterError::Serialization(e) => Error::SerializeRecord(e.into()), } } diff --git a/spdlog/src/formatter/pattern_formatter/mod.rs b/spdlog/src/formatter/pattern_formatter/mod.rs index e15d1c61..f3c09386 100644 --- a/spdlog/src/formatter/pattern_formatter/mod.rs +++ b/spdlog/src/formatter/pattern_formatter/mod.rs @@ -161,7 +161,7 @@ use crate::{ /// /// impl Pattern for MyPattern { /// fn format(&self, record: &Record, dest: &mut StringBuf, _: &mut PatternContext) -> spdlog::Result<()> { -/// write!(dest, "My own pattern").map_err(spdlog::Error::FormatRecord) +/// write!(dest, "My own pattern").map_err(|err| spdlog::Error::FormatRecord(err.into())) /// } /// } /// @@ -225,7 +225,7 @@ use crate::{ /// /// impl Pattern for MyPattern { /// fn format(&self, record: &Record, dest: &mut StringBuf, _: &mut PatternContext) -> spdlog::Result<()> { -/// write!(dest, "{}", self.id).map_err(spdlog::Error::FormatRecord) +/// write!(dest, "{}", self.id).map_err(|err| spdlog::Error::FormatRecord(err.into())) /// } /// } /// @@ -472,7 +472,8 @@ impl Pattern for str { dest: &mut StringBuf, _ctx: &mut PatternContext, ) -> crate::Result<()> { - dest.write_str(self).map_err(Error::FormatRecord) + dest.write_str(self) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/datetime.rs b/spdlog/src/formatter/pattern_formatter/pattern/datetime.rs index 383bc108..f36c6843 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/datetime.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/datetime.rs @@ -18,7 +18,7 @@ impl Pattern for AbbrWeekdayName { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().weekday_name().short) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -35,7 +35,7 @@ impl Pattern for WeekdayName { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().weekday_name().full) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -52,7 +52,7 @@ impl Pattern for AbbrMonthName { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().month_name().short) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -69,7 +69,7 @@ impl Pattern for MonthName { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().month_name().full) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -100,7 +100,7 @@ impl Pattern for FullDateTime { dest.write_char(' ')?; dest.write_str(ctx.time_date().year_str()) })() - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -117,7 +117,7 @@ impl Pattern for ShortYear { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().year_short_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -134,7 +134,7 @@ impl Pattern for Year { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().year_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -157,7 +157,7 @@ impl Pattern for Date { dest.write_char('-')?; dest.write_str(ctx.time_date().day_str()) })() - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -180,7 +180,7 @@ impl Pattern for ShortDate { dest.write_char('/')?; dest.write_str(ctx.time_date().year_short_str()) })() - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -197,7 +197,7 @@ impl Pattern for Month { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().month_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -214,7 +214,7 @@ impl Pattern for Day { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().day_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -231,7 +231,7 @@ impl Pattern for Hour { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().hour_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -248,7 +248,7 @@ impl Pattern for Hour12 { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().hour12_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -265,7 +265,7 @@ impl Pattern for Minute { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().minute_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -282,7 +282,7 @@ impl Pattern for Second { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().second_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -302,7 +302,8 @@ impl Pattern for Millisecond { dest: &mut StringBuf, ctx: &mut PatternContext, ) -> crate::Result<()> { - write!(dest, "{:03}", ctx.time_date().millisecond()).map_err(Error::FormatRecord) + write!(dest, "{:03}", ctx.time_date().millisecond()) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -319,7 +320,7 @@ impl Pattern for Microsecond { ctx: &mut PatternContext, ) -> crate::Result<()> { let nanosecond = ctx.time_date().nanosecond(); - write!(dest, "{:06}", nanosecond / 1_000).map_err(Error::FormatRecord) + write!(dest, "{:06}", nanosecond / 1_000).map_err(|err| Error::FormatRecord(err.into())) } } @@ -335,7 +336,8 @@ impl Pattern for Nanosecond { dest: &mut StringBuf, ctx: &mut PatternContext, ) -> crate::Result<()> { - write!(dest, "{:09}", ctx.time_date().nanosecond()).map_err(Error::FormatRecord) + write!(dest, "{:09}", ctx.time_date().nanosecond()) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -352,7 +354,7 @@ impl Pattern for AmPm { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().am_pm_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -377,7 +379,7 @@ impl Pattern for Time12 { dest.write_str(" ")?; dest.write_str(ctx.time_date().am_pm_str()) })() - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -398,7 +400,7 @@ impl Pattern for ShortTime { dest.write_char(':')?; dest.write_str(ctx.time_date().minute_str()) })() - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -421,7 +423,7 @@ impl Pattern for Time { dest.write_char(':')?; dest.write_str(ctx.time_date().second_str()) })() - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -438,7 +440,7 @@ impl Pattern for TzOffset { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().tz_offset_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -455,6 +457,6 @@ impl Pattern for UnixTimestamp { ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(ctx.time_date().unix_timestamp_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/eol.rs b/spdlog/src/formatter/pattern_formatter/pattern/eol.rs index b40cd03f..d4f8da10 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/eol.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/eol.rs @@ -22,6 +22,7 @@ impl Pattern for Eol { dest: &mut StringBuf, _ctx: &mut PatternContext, ) -> crate::Result<()> { - dest.write_str(crate::__EOL).map_err(Error::FormatRecord) + dest.write_str(crate::__EOL) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/level.rs b/spdlog/src/formatter/pattern_formatter/pattern/level.rs index 91992033..8db81d8f 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/level.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/level.rs @@ -18,7 +18,7 @@ impl Pattern for Level { _ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(record.level().as_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } @@ -35,6 +35,6 @@ impl Pattern for ShortLevel { _ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(record.level().as_short_str()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/logger_name.rs b/spdlog/src/formatter/pattern_formatter/pattern/logger_name.rs index 4d59ccf3..56f737de 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/logger_name.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/logger_name.rs @@ -18,6 +18,6 @@ impl Pattern for LoggerName { _ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(record.logger_name().unwrap_or("")) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/payload.rs b/spdlog/src/formatter/pattern_formatter/pattern/payload.rs index a0ed1b7e..5992c5e3 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/payload.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/payload.rs @@ -18,6 +18,6 @@ impl Pattern for Payload { _ctx: &mut PatternContext, ) -> crate::Result<()> { dest.write_str(record.payload()) - .map_err(Error::FormatRecord) + .map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/process_id.rs b/spdlog/src/formatter/pattern_formatter/pattern/process_id.rs index 0432336c..60c49167 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/process_id.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/process_id.rs @@ -26,7 +26,7 @@ impl Pattern for ProcessId { _ctx: &mut PatternContext, ) -> crate::Result<()> { let pid = get_current_process_id(); - write!(dest, "{}", pid).map_err(Error::FormatRecord) + write!(dest, "{}", pid).map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/srcloc.rs b/spdlog/src/formatter/pattern_formatter/pattern/srcloc.rs index 6ce115a0..e049ed52 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/srcloc.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/srcloc.rs @@ -23,7 +23,7 @@ impl Pattern for Source { dest.write_char(':')?; write!(dest, "{}", loc.line()) })() - .map_err(Error::FormatRecord)?; + .map_err(|err| Error::FormatRecord(err.into()))?; } Ok(()) } @@ -43,7 +43,7 @@ impl Pattern for SourceFilename { ) -> crate::Result<()> { if let Some(loc) = record.source_location() { dest.write_str(loc.file_name()) - .map_err(Error::FormatRecord)?; + .map_err(|err| Error::FormatRecord(err.into()))?; } Ok(()) } @@ -62,7 +62,8 @@ impl Pattern for SourceFile { _ctx: &mut PatternContext, ) -> crate::Result<()> { if let Some(loc) = record.source_location() { - dest.write_str(loc.file()).map_err(Error::FormatRecord)?; + dest.write_str(loc.file()) + .map_err(|err| Error::FormatRecord(err.into()))?; } Ok(()) } @@ -80,7 +81,7 @@ impl Pattern for SourceLine { _ctx: &mut PatternContext, ) -> crate::Result<()> { if let Some(loc) = record.source_location() { - write!(dest, "{}", loc.line()).map_err(Error::FormatRecord)?; + write!(dest, "{}", loc.line()).map_err(|err| Error::FormatRecord(err.into()))?; } Ok(()) } @@ -98,7 +99,7 @@ impl Pattern for SourceColumn { _ctx: &mut PatternContext, ) -> crate::Result<()> { if let Some(loc) = record.source_location() { - write!(dest, "{}", loc.column()).map_err(Error::FormatRecord)?; + write!(dest, "{}", loc.column()).map_err(|err| Error::FormatRecord(err.into()))?; } Ok(()) } @@ -118,7 +119,7 @@ impl Pattern for SourceModulePath { ) -> crate::Result<()> { if let Some(loc) = record.source_location() { dest.write_str(loc.module_path()) - .map_err(Error::FormatRecord)?; + .map_err(|err| Error::FormatRecord(err.into()))?; } Ok(()) } diff --git a/spdlog/src/formatter/pattern_formatter/pattern/thread_id.rs b/spdlog/src/formatter/pattern_formatter/pattern/thread_id.rs index 8e975079..1367be46 100644 --- a/spdlog/src/formatter/pattern_formatter/pattern/thread_id.rs +++ b/spdlog/src/formatter/pattern_formatter/pattern/thread_id.rs @@ -27,6 +27,6 @@ impl Pattern for ThreadId { dest: &mut StringBuf, _ctx: &mut PatternContext, ) -> crate::Result<()> { - write!(dest, "{}", record.tid()).map_err(Error::FormatRecord) + write!(dest, "{}", record.tid()).map_err(|err| Error::FormatRecord(err.into())) } } diff --git a/spdlog/src/formatter/pattern_formatter/runtime.rs b/spdlog/src/formatter/pattern_formatter/runtime.rs index 8d643a26..a287ede3 100644 --- a/spdlog/src/formatter/pattern_formatter/runtime.rs +++ b/spdlog/src/formatter/pattern_formatter/runtime.rs @@ -98,7 +98,7 @@ pub use spdlog_macros::runtime_pattern; /// /// impl Pattern for MyPattern { /// fn format(&self, record: &Record, dest: &mut StringBuf, _: &mut PatternContext) -> spdlog::Result<()> { -/// write!(dest, "My own pattern").map_err(spdlog::Error::FormatRecord) +/// write!(dest, "My own pattern").map_err(|err| spdlog::Error::FormatRecord(err.into())) /// } /// } /// diff --git a/spdlog/src/lib.rs b/spdlog/src/lib.rs index 486bc424..93f490a5 100644 --- a/spdlog/src/lib.rs +++ b/spdlog/src/lib.rs @@ -758,25 +758,6 @@ fn flush_default_logger_at_exit() { } } -fn default_error_handler(from: impl AsRef, error: Error) { - if let Error::Multiple(errs) = error { - errs.into_iter() - .for_each(|err| default_error_handler(from.as_ref(), err)); - return; - } - - let date = chrono::Local::now() - .format("%Y-%m-%d %H:%M:%S.%3f") - .to_string(); - - eprintln!( - "[*** SPDLOG-RS UNHANDLED ERROR ***] [{}] [{}] {}", - date, - from.as_ref(), - error - ); -} - // Used at log macros #[doc(hidden)] pub fn __log( diff --git a/spdlog/src/logger.rs b/spdlog/src/logger.rs index 1996af57..83153af6 100644 --- a/spdlog/src/logger.rs +++ b/spdlog/src/logger.rs @@ -111,7 +111,7 @@ pub struct Logger { level_filter: Atomic, sinks: Sinks, flush_level_filter: Atomic, - error_handler: SpinRwLock>, + error_handler: SpinRwLock, periodic_flusher: Mutex>, } @@ -148,14 +148,14 @@ impl Debug for Logger { impl Logger { /// Gets a [`LoggerBuilder`] with default parameters: /// - /// | Parameter | Default Value | - /// |----------------------|-------------------------| - /// | [name] | `None` | - /// | [sinks] | `[]` | - /// | [level_filter] | `MoreSevereEqual(Info)` | - /// | [flush_level_filter] | `Off` | - /// | [flush_period] | `None` | - /// | [error_handler] | [default error handler] | + /// | Parameter | Default Value | + /// |----------------------|-----------------------------| + /// | [name] | `None` | + /// | [sinks] | `[]` | + /// | [level_filter] | `MoreSevereEqual(Info)` | + /// | [flush_level_filter] | `Off` | + /// | [flush_period] | `None` | + /// | [error_handler] | [`ErrorHandler::default()`] | /// /// [name]: LoggerBuilder::name /// [sinks]: LoggerBuilder::sink @@ -163,7 +163,7 @@ impl Logger { /// [flush_level_filter]: LoggerBuilder::flush_level_filter /// [flush_period]: Logger::set_flush_period /// [error_handler]: LoggerBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() #[must_use] pub fn builder() -> LoggerBuilder { LoggerBuilder { @@ -171,7 +171,7 @@ impl Logger { level_filter: LevelFilter::MoreSevereEqual(Level::Info), sinks: vec![], flush_level_filter: LevelFilter::Off, - error_handler: None, + error_handler: ErrorHandler::default(), } } @@ -377,14 +377,17 @@ impl Logger { /// # Examples /// /// ``` - /// use spdlog::prelude::*; + /// use spdlog::{prelude::*, ErrorHandler}; /// - /// spdlog::default_logger().set_error_handler(Some(|err| { + /// spdlog::default_logger().set_error_handler(ErrorHandler::new(|err| { /// panic!("An error occurred in the default logger: {}", err) /// })); /// ``` - pub fn set_error_handler(&self, handler: Option) { - *self.error_handler.write() = handler; + pub fn set_error_handler(&self, handler: H) + where + H: Into, + { + *self.error_handler.write() = handler.into(); } /// Forks and configures a separate new logger. @@ -506,17 +509,13 @@ impl Logger { } fn handle_error(&self, err: Error) { - if let Some(handler) = self.error_handler.read().as_ref() { - handler(err) - } else { - crate::default_error_handler( - format!( - "Logger ({})", - self.name.as_ref().map_or("*no name*", String::as_str) - ), - err, - ); - } + self.error_handler.read().call_internal( + format!( + "Logger ({})", + self.name.as_ref().map_or("*no name*", String::as_str) + ), + err, + ) } #[must_use] @@ -550,7 +549,7 @@ pub struct LoggerBuilder { level_filter: LevelFilter, sinks: Sinks, flush_level_filter: LevelFilter, - error_handler: Option, + error_handler: ErrorHandler, } impl LoggerBuilder { @@ -624,8 +623,11 @@ impl LoggerBuilder { /// /// See the documentation of [`Logger::set_error_handler`] for the /// description of this parameter. - pub fn error_handler(&mut self, handler: ErrorHandler) -> &mut Self { - self.error_handler = Some(handler); + pub fn error_handler(&mut self, handler: H) -> &mut Self + where + H: Into, + { + self.error_handler = handler.into(); self } diff --git a/spdlog/src/sink/async_sink/async_pool_sink.rs b/spdlog/src/sink/async_sink/async_pool_sink.rs index a622b035..0a0f82b5 100644 --- a/spdlog/src/sink/async_sink/async_pool_sink.rs +++ b/spdlog/src/sink/async_sink/async_pool_sink.rs @@ -1,5 +1,5 @@ use crate::{ - default_error_handler, default_thread_pool, + default_thread_pool, formatter::Formatter, sink::{helper, OverflowPolicy, Sink, Sinks}, sync::*, @@ -58,13 +58,12 @@ impl AsyncPoolSink { /// | Parameter | Default Value | /// |-------------------|-------------------------------------| /// | [level_filter] | `All` | - /// | [error_handler] | [default error handler] | + /// | [error_handler] | [`ErrorHandler::default()`] | /// | [overflow_policy] | `Block` | /// | [thread_pool] | internal shared default thread pool | /// /// [level_filter]: AsyncPoolSinkBuilder::level_filter /// [error_handler]: AsyncPoolSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler /// [overflow_policy]: AsyncPoolSinkBuilder::overflow_policy /// [thread_pool]: AsyncPoolSinkBuilder::thread_pool #[must_use] @@ -74,7 +73,7 @@ impl AsyncPoolSink { overflow_policy: OverflowPolicy::Block, sinks: Sinks::new(), thread_pool: None, - error_handler: None, + error_handler: ErrorHandler::default(), } } @@ -85,7 +84,7 @@ impl AsyncPoolSink { } /// Sets a error handler. - pub fn set_error_handler(&self, handler: Option) { + pub fn set_error_handler(&self, handler: ErrorHandler) { self.backend.error_handler.swap(handler, Ordering::Relaxed); } @@ -148,7 +147,7 @@ pub struct AsyncPoolSinkBuilder { sinks: Sinks, overflow_policy: OverflowPolicy, thread_pool: Option>, - error_handler: Option, + error_handler: ErrorHandler, } impl AsyncPoolSinkBuilder { @@ -239,7 +238,7 @@ impl Backend { fn handle_error(&self, err: Error) { self.error_handler .load(Ordering::Relaxed) - .unwrap_or(|err| default_error_handler("AsyncPoolSink", err))(err); + .call_internal("AsyncPoolSink", err); } } diff --git a/spdlog/src/sink/dedup_sink.rs b/spdlog/src/sink/dedup_sink.rs index 8e375ed9..60b4cbf7 100644 --- a/spdlog/src/sink/dedup_sink.rs +++ b/spdlog/src/sink/dedup_sink.rs @@ -88,19 +88,19 @@ pub struct DedupSink { impl DedupSink { /// Gets a builder of `DedupSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-----------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | - /// | [error_handler] | [default error handler] | - /// | | | - /// | [sinks] | `[]` | - /// | [skip_duration] | *must be specified* | + /// | Parameter | Default Value | + /// |-----------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | + /// | | | + /// | [sinks] | `[]` | + /// | [skip_duration] | *must be specified* | /// /// [level_filter]: DedupSinkBuilder::level_filter /// [formatter]: DedupSinkBuilder::formatter /// [error_handler]: DedupSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() /// [sinks]: DedupSinkBuilder::sink /// [skip_duration]: DedupSinkBuilder::skip_duration #[must_use] diff --git a/spdlog/src/sink/file_sink.rs b/spdlog/src/sink/file_sink.rs index 7f3f775c..57a0adab 100644 --- a/spdlog/src/sink/file_sink.rs +++ b/spdlog/src/sink/file_sink.rs @@ -35,19 +35,19 @@ pub struct FileSink { impl FileSink { /// Gets a builder of `FileSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-----------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | - /// | [error_handler] | [default error handler] | - /// | | | - /// | [path] | *must be specified* | - /// | [truncate] | `false` | + /// | Parameter | Default Value | + /// |-----------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | + /// | | | + /// | [path] | *must be specified* | + /// | [truncate] | `false` | /// /// [level_filter]: FileSinkBuilder::level_filter /// [formatter]: FileSinkBuilder::formatter /// [error_handler]: FileSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() /// [path]: FileSinkBuilder::path /// [truncate]: FileSinkBuilder::truncate #[must_use] @@ -96,13 +96,16 @@ impl Sink for FileSink { self.file .lock() .write_all(string_buf.as_bytes()) - .map_err(Error::WriteRecord)?; + .map_err(|err| Error::WriteRecord(err.into()))?; Ok(()) } fn flush(&self) -> Result<()> { - self.file.lock().flush().map_err(Error::FlushBuffer) + self.file + .lock() + .flush() + .map_err(|err| Error::FlushBuffer(err.into())) } helper::common_impl!(@Sink: common_impl); @@ -112,7 +115,7 @@ impl Drop for FileSink { fn drop(&mut self) { if let Err(err) = self.file.lock().flush() { self.common_impl - .non_returnable_error("FileSink", Error::FlushBuffer(err)) + .non_returnable_error("FileSink", Error::FlushBuffer(err.into())) } } } diff --git a/spdlog/src/sink/helper.rs b/spdlog/src/sink/helper.rs index f970346e..9c4d7e3e 100644 --- a/spdlog/src/sink/helper.rs +++ b/spdlog/src/sink/helper.rs @@ -7,7 +7,7 @@ use crate::{ Error, ErrorHandler, }; -pub(crate) type SinkErrorHandler = Atomic>; +pub(crate) type SinkErrorHandler = Atomic; cfg_if! { if #[cfg(test)] { @@ -47,22 +47,21 @@ impl CommonImpl { Self { level_filter: Atomic::new(LevelFilter::All), formatter: SpinRwLock::new(formatter), - error_handler: Atomic::new(None), + error_handler: Atomic::new(ErrorHandler::default()), } } pub(crate) fn non_returnable_error(&self, from: impl AsRef, err: Error) { - match self.error_handler.load(Ordering::Relaxed) { - Some(handler) => handler(err), - None => crate::default_error_handler(from, err), - } + self.error_handler + .load(Ordering::Relaxed) + .call_internal(from, err) } } pub(crate) struct CommonBuilderImpl { pub(crate) level_filter: LevelFilter, pub(crate) formatter: Option>, - pub(crate) error_handler: Option, + pub(crate) error_handler: ErrorHandler, } impl CommonBuilderImpl { @@ -71,7 +70,7 @@ impl CommonBuilderImpl { Self { level_filter: SINK_DEFAULT_LEVEL_FILTER, formatter: None, - error_handler: None, + error_handler: ErrorHandler::default(), } } } @@ -113,7 +112,7 @@ macro_rules! common_impl { }; ( @SinkCustomInner@error_handler: None ) => {}; ( @SinkCustomInner@error_handler: $($field:ident).+ ) => { - fn set_error_handler(&self, handler: Option<$crate::ErrorHandler>) { + fn set_error_handler(&self, handler: $crate::ErrorHandler) { self.$($field).+.store(handler, $crate::sync::Ordering::Relaxed); } }; @@ -180,8 +179,11 @@ macro_rules! common_impl { ( $(#[$attr:meta])* @SinkBuilderCustomInner@error_handler: $($field:ident).+ ) => { $(#[$attr])* #[must_use] - pub fn error_handler(mut self, handler: $crate::ErrorHandler) -> Self { - self.$($field).+ = Some(handler); + pub fn error_handler(mut self, handler: H) -> Self + where + H: Into<$crate::ErrorHandler> + { + self.$($field).+ = handler.into(); self } }; diff --git a/spdlog/src/sink/journald_sink.rs b/spdlog/src/sink/journald_sink.rs index 7b0fc574..9d5f4e1d 100644 --- a/spdlog/src/sink/journald_sink.rs +++ b/spdlog/src/sink/journald_sink.rs @@ -96,16 +96,16 @@ impl JournaldSink { /// Gets a builder of `JournaldSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-----------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `JournaldFormatter` | - /// | [error_handler] | [default error handler] | + /// | Parameter | Default Value | + /// |-----------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `JournaldFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | /// /// [level_filter]: JournaldSinkBuilder::level_filter /// [formatter]: JournaldSinkBuilder::formatter /// [error_handler]: JournaldSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() #[must_use] pub fn builder() -> JournaldSinkBuilder { JournaldSinkBuilder { @@ -139,7 +139,8 @@ impl Sink for JournaldSink { None => [None, None], }; - journal_send(kvs.iter().chain(srcloc_kvs.iter().flatten())).map_err(Error::WriteRecord) + journal_send(kvs.iter().chain(srcloc_kvs.iter().flatten())) + .map_err(|err| Error::WriteRecord(err.into())) } fn flush(&self) -> Result<()> { diff --git a/spdlog/src/sink/mod.rs b/spdlog/src/sink/mod.rs index 844eb1a4..3223e58d 100644 --- a/spdlog/src/sink/mod.rs +++ b/spdlog/src/sink/mod.rs @@ -83,11 +83,8 @@ pub trait Sink: Sync + Send { /// returned immediately, this function will be called. For example, /// asynchronous errors. /// - /// If no handler is set, [default error handler] will be used. - /// /// [`Logger`]: crate::logger::Logger - /// [default error handler]: ../error/index.html#default-error-handler - fn set_error_handler(&self, handler: Option); + fn set_error_handler(&self, handler: ErrorHandler); } /// Container type for [`Sink`]s. diff --git a/spdlog/src/sink/rotating_file_sink.rs b/spdlog/src/sink/rotating_file_sink.rs index ea7dc015..243ab899 100644 --- a/spdlog/src/sink/rotating_file_sink.rs +++ b/spdlog/src/sink/rotating_file_sink.rs @@ -163,21 +163,21 @@ pub struct RotatingFileSinkBuilder { impl RotatingFileSink { /// Gets a builder of `RotatingFileSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-------------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | - /// | [error_handler] | [default error handler] | - /// | | | - /// | [base_path] | *must be specified* | - /// | [rotation_policy] | *must be specified* | - /// | [max_files] | `0` | - /// | [rotate_on_open] | `false` | + /// | Parameter | Default Value | + /// |-------------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | + /// | | | + /// | [base_path] | *must be specified* | + /// | [rotation_policy] | *must be specified* | + /// | [max_files] | `0` | + /// | [rotate_on_open] | `false` | /// /// [level_filter]: RotatingFileSinkBuilder::level_filter /// [formatter]: RotatingFileSinkBuilder::formatter /// [error_handler]: RotatingFileSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() /// [base_path]: RotatingFileSinkBuilder::base_path /// [rotation_policy]: RotatingFileSinkBuilder::rotation_policy /// [max_files]: RotatingFileSinkBuilder::max_files @@ -443,7 +443,7 @@ impl Rotator for RotatorFileSize { .as_mut() .unwrap() .write_all(string_buf.as_bytes()) - .map_err(Error::WriteRecord) + .map_err(|err| Error::WriteRecord(err.into())) } fn flush(&self) -> Result<()> { @@ -452,13 +452,13 @@ impl Rotator for RotatorFileSize { .as_mut() .unwrap() .flush() - .map_err(Error::FlushBuffer) + .map_err(|err| Error::FlushBuffer(err.into())) } fn drop_flush(&mut self) -> Result<()> { let mut inner = self.inner.lock(); if let Some(file) = inner.file.as_mut() { - file.flush().map_err(Error::FlushBuffer) + file.flush().map_err(|err| Error::FlushBuffer(err.into())) } else { Ok(()) } @@ -662,7 +662,7 @@ impl Rotator for RotatorTimePoint { inner .file .write_all(string_buf.as_bytes()) - .map_err(Error::WriteRecord)?; + .map_err(|err| Error::WriteRecord(err.into()))?; if should_rotate && inner.file_paths.is_some() { self.push_new_remove_old(file_path.unwrap(), &mut inner)?; @@ -672,7 +672,11 @@ impl Rotator for RotatorTimePoint { } fn flush(&self) -> Result<()> { - self.inner.lock().file.flush().map_err(Error::FlushBuffer) + self.inner + .lock() + .file + .flush() + .map_err(|err| Error::FlushBuffer(err.into())) } } diff --git a/spdlog/src/sink/std_stream_sink.rs b/spdlog/src/sink/std_stream_sink.rs index 380c920e..fed0bae3 100644 --- a/spdlog/src/sink/std_stream_sink.rs +++ b/spdlog/src/sink/std_stream_sink.rs @@ -3,6 +3,7 @@ use std::{ convert::Infallible, io::{self, Write}, + result::Result as StdResult, }; use if_chain::if_chain; @@ -95,19 +96,19 @@ pub struct StdStreamSink { impl StdStreamSink { /// Gets a builder of `StdStreamSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-------------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | - /// | [error_handler] | [default error handler] | - /// | | | - /// | [std_stream] | *must be specified* | - /// | [style_mode] | `Auto` | + /// | Parameter | Default Value | + /// |-------------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | + /// | | | + /// | [std_stream] | *must be specified* | + /// | [style_mode] | `Auto` | /// /// [level_filter]: StdStreamSinkBuilder::level_filter /// [formatter]: StdStreamSinkBuilder::formatter /// [error_handler]: StdStreamSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() /// [std_stream]: StdStreamSinkBuilder::std_stream /// [style_mode]: StdStreamSinkBuilder::style_mode #[must_use] @@ -170,7 +171,7 @@ impl Sink for StdStreamSink { let mut dest = self.dest.lock(); - (|| { + (|| -> StdResult<(), io::Error> { if_chain! { if self.should_render_style; if let Some(style_range) = ctx.style_range(); @@ -188,19 +189,22 @@ impl Sink for StdStreamSink { } Ok(()) })() - .map_err(Error::WriteRecord)?; + .map_err(|err| Error::WriteRecord(err.into()))?; // stderr is not buffered, so we don't need to flush it. // https://doc.rust-lang.org/std/io/fn.stderr.html if let StdStreamDest::Stdout(_) = dest { - dest.flush().map_err(Error::FlushBuffer)?; + dest.flush().map_err(|err| Error::FlushBuffer(err.into()))?; } Ok(()) } fn flush(&self) -> Result<()> { - self.dest.lock().flush().map_err(Error::FlushBuffer) + self.dest + .lock() + .flush() + .map_err(|err| Error::FlushBuffer(err.into())) } helper::common_impl!(@Sink: common_impl); diff --git a/spdlog/src/sink/win_debug_sink.rs b/spdlog/src/sink/win_debug_sink.rs index 79fb45d5..1773654a 100644 --- a/spdlog/src/sink/win_debug_sink.rs +++ b/spdlog/src/sink/win_debug_sink.rs @@ -14,16 +14,16 @@ pub struct WinDebugSink { impl WinDebugSink { /// Gets a builder of `WinDebugSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-----------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | - /// | [error_handler] | [default error handler] | + /// | Parameter | Default Value | + /// |-----------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | /// /// [level_filter]: WinDebugSinkBuilder::level_filter /// [formatter]: WinDebugSinkBuilder::formatter /// [error_handler]: WinDebugSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() #[must_use] pub fn builder() -> WinDebugSinkBuilder { WinDebugSinkBuilder { diff --git a/spdlog/src/sink/write_sink.rs b/spdlog/src/sink/write_sink.rs index f14da832..49e78662 100644 --- a/spdlog/src/sink/write_sink.rs +++ b/spdlog/src/sink/write_sink.rs @@ -39,18 +39,18 @@ where { /// Gets a builder of `WriteSink` with default parameters: /// - /// | Parameter | Default Value | - /// |-------------------|-------------------------| - /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | - /// | [error_handler] | [default error handler] | - /// | | | - /// | [target] | *must be specified* | + /// | Parameter | Default Value | + /// |-------------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | + /// | | | + /// | [target] | *must be specified* | /// /// [level_filter]: WriteSinkBuilder::level_filter /// [formatter]: WriteSinkBuilder::formatter /// [error_handler]: WriteSinkBuilder::error_handler - /// [default error handler]: error/index.html#default-error-handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() /// [target]: WriteSinkBuilder::target #[must_use] pub fn builder() -> WriteSinkBuilder { @@ -109,13 +109,15 @@ where self.lock_target() .write_all(string_buf.as_bytes()) - .map_err(Error::WriteRecord)?; + .map_err(|err| Error::WriteRecord(err.into()))?; Ok(()) } fn flush(&self) -> Result<()> { - self.lock_target().flush().map_err(Error::FlushBuffer) + self.lock_target() + .flush() + .map_err(|err| Error::FlushBuffer(err.into())) } helper::common_impl!(@Sink: common_impl); @@ -126,7 +128,10 @@ where W: Write + Send, { fn drop(&mut self) { - let flush_result = self.lock_target().flush().map_err(Error::FlushBuffer); + let flush_result = self + .lock_target() + .flush() + .map_err(|err| Error::FlushBuffer(err.into())); if let Err(err) = flush_result { self.common_impl.non_returnable_error("WriteSink", err) } diff --git a/spdlog/src/test_utils/common.rs b/spdlog/src/test_utils/common.rs index c0ae26d0..7b05379f 100644 --- a/spdlog/src/test_utils/common.rs +++ b/spdlog/src/test_utils/common.rs @@ -114,7 +114,7 @@ impl Sink for TestSink { unimplemented!("no-op") } - fn set_error_handler(&self, _handler: Option) { + fn set_error_handler(&self, _handler: ErrorHandler) { unimplemented!("no-op") } } @@ -174,7 +174,7 @@ impl Sink for StringSink { self.underlying.set_formatter(formatter) } - fn set_error_handler(&self, handler: Option) { + fn set_error_handler(&self, handler: ErrorHandler) { self.underlying.set_error_handler(handler) } } @@ -200,7 +200,7 @@ impl Formatter for NoModFormatter { _ctx: &mut FormatterContext, ) -> Result<()> { dest.write_str(record.payload()) - .map_err(Error::FormatRecord)?; + .map_err(|err| Error::FormatRecord(err.into()))?; Ok(()) } } @@ -216,7 +216,7 @@ impl Default for NoModFormatter { #[must_use] pub fn build_test_logger(cb: impl FnOnce(&mut LoggerBuilder) -> &mut LoggerBuilder) -> Logger { let mut builder = Logger::builder(); - cb(builder.error_handler(|err| panic!("{}", err))); + cb(builder.error_handler(ErrorHandler::new(|err| panic!("{}", err)))); builder.build().unwrap() } diff --git a/spdlog/tests/global_async_pool_sink.rs b/spdlog/tests/global_async_pool_sink.rs index e430ac0f..705eee1d 100644 --- a/spdlog/tests/global_async_pool_sink.rs +++ b/spdlog/tests/global_async_pool_sink.rs @@ -46,7 +46,7 @@ impl Sink for SetFlagSink { unimplemented!() } - fn set_error_handler(&self, _handler: Option) { + fn set_error_handler(&self, _handler: ErrorHandler) { unimplemented!() } } diff --git a/spdlog/tests/pattern.rs b/spdlog/tests/pattern.rs index 301a4ad9..0f06a54a 100644 --- a/spdlog/tests/pattern.rs +++ b/spdlog/tests/pattern.rs @@ -161,7 +161,7 @@ impl Sink for MockSink { *self.formatter.lock().unwrap() = Some(formatter); } - fn set_error_handler(&self, _handler: Option) {} + fn set_error_handler(&self, _handler: spdlog::ErrorHandler) {} fn should_log(&self, _level: spdlog::Level) -> bool { true