Skip to content

Commit 2cf7b29

Browse files
authored
refactor!: simplify source error (#223)
Signed-off-by: tison <wander4096@gmail.com>
1 parent 38ad624 commit 2cf7b29

2 files changed

Lines changed: 20 additions & 21 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
1111
* `Async` appender's `flush` method is now blocking until all buffered logs are flushed by worker threads. Any errors during flushing will be propagated back to the `flush` caller.
1212
* `Record::payload` is now `std::fmt::Arguments` instead of `Cow<'static, str>`.
1313
* `RecordOwned::as_record` has been removed; use `RecordOwned::with` instead. (This is a limitation of Rust as described [here](https://github.com/rust-lang/rust/issues/92698#issuecomment-3311144848).)
14+
* `logforth_core::Error::with_source` now set the optional source field instead of append a sources list.
1415

1516
## [0.29.1] 2025-11-03
1617

core/src/error.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::io;
1818
/// The error struct of logforth.
1919
pub struct Error {
2020
message: String,
21-
sources: Vec<anyhow::Error>,
21+
source: Option<anyhow::Error>,
2222
context: Vec<(&'static str, String)>,
2323
}
2424

@@ -40,15 +40,8 @@ impl fmt::Display for Error {
4040
write!(f, " }}")?;
4141
}
4242

43-
if !self.sources.is_empty() {
44-
write!(f, ", sources: [")?;
45-
for (i, source) in self.sources.iter().enumerate() {
46-
if i > 0 {
47-
write!(f, ", ")?;
48-
}
49-
write!(f, "{source}")?;
50-
}
51-
write!(f, "]")?;
43+
if let Some(source) = &self.source {
44+
write!(f, ", source: {source}")?;
5245
}
5346

5447
Ok(())
@@ -62,7 +55,7 @@ impl fmt::Debug for Error {
6255
let mut de = f.debug_struct("Error");
6356
de.field("message", &self.message);
6457
de.field("context", &self.context);
65-
de.field("sources", &self.sources);
58+
de.field("sources", &self.source);
6659
return de.finish();
6760
}
6861

@@ -76,12 +69,11 @@ impl fmt::Debug for Error {
7669
writeln!(f, " {k}: {v}")?;
7770
}
7871
}
79-
if !self.sources.is_empty() {
72+
73+
if let Some(source) = &self.source {
8074
writeln!(f)?;
81-
writeln!(f, "Sources:")?;
82-
for source in self.sources.iter() {
83-
writeln!(f, " {source:#}")?;
84-
}
75+
writeln!(f, "Source:")?;
76+
writeln!(f, " {source:#}")?;
8577
}
8678

8779
Ok(())
@@ -90,7 +82,7 @@ impl fmt::Debug for Error {
9082

9183
impl std::error::Error for Error {
9284
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
93-
self.sources.first().map(|v| v.as_ref())
85+
self.source.as_ref().map(|v| v.as_ref())
9486
}
9587
}
9688

@@ -99,7 +91,7 @@ impl Error {
9991
pub fn new(message: impl Into<String>) -> Self {
10092
Self {
10193
message: message.into(),
102-
sources: vec![],
94+
source: None,
10395
context: vec![],
10496
}
10597
}
@@ -110,15 +102,21 @@ impl Error {
110102
self
111103
}
112104

113-
/// Add one more source in error.
105+
/// Set source for error.
106+
///
107+
/// # Panics
108+
///
109+
/// If the source has been set, we will raise a panic here.
114110
pub fn with_source(mut self, src: impl Into<anyhow::Error>) -> Self {
115-
self.sources.push(src.into());
111+
assert!(self.source.is_none(), "the source error has been set");
112+
113+
self.source = Some(src.into());
116114
self
117115
}
118116

119117
/// Return an iterator over all sources of this error.
120118
pub fn sources(&self) -> impl ExactSizeIterator<Item = &(dyn std::error::Error + 'static)> {
121-
self.sources.iter().map(|v| v.as_ref())
119+
self.source.iter().map(|v| v.as_ref())
122120
}
123121

124122
/// Default constructor for [`Error`] from [`io::Error`].

0 commit comments

Comments
 (0)