From 9811fd4eb70aa1a5711f4f9aa42c8d5156f28fb3 Mon Sep 17 00:00:00 2001 From: Robin Lu Date: Tue, 31 Dec 2024 10:07:01 +0800 Subject: [PATCH] Fix: Continue iteration after recoverable errors in SdrIter Signed-off-by: Robin Lu --- src/lib.rs | 112 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 39 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b8dcb2c..c8c38a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -113,51 +113,85 @@ where type Item = SdrRecord; fn next(&mut self) -> Option { - let current_id = self.next_id?; + let mut recoverable_errors = 0; + const MAX_RECOVERABLE_ERRORS: usize = 10; // Max number of recoverable errors - if current_id.is_last() { - self.next_id.take(); - return None; - } - - let next_record = self - .ipmi - .send_recv(sdr::GetDeviceSdr::new(None, current_id)); - - let (value, next_record_id) = match next_record { - Ok(record) => { - let next_record_id = record.next_entry; - - (Some(record.record), next_record_id) - } - Err(IpmiError::ParsingFailed { - error: ParseResponseError::Parse((e, next_record_id)), - .. - }) => { - log::warn!( - "Recoverable error while parsing SDR record 0x{:04X}: {e:?}", - current_id.value() - ); - (None, next_record_id) - } - Err(e) => { - log::error!( - "Unrecoverable error while parsing SDR record 0x{:04X}: {e:?}", - current_id.value() - ); + while let Some(current_id) = self.next_id { + if current_id.is_last() { self.next_id.take(); + if recoverable_errors > 0 { + log::warn!( + "Iteration completed with {} recoverable errors.", + recoverable_errors + ); + } return None; } - }; - if next_record_id == current_id { - log::error!("Got duplicate SDR record IDs! Stopping iteration."); - self.next_id.take(); - return None; - } else { - self.next_id = Some(next_record_id); + let next_record = self + .ipmi + .send_recv(sdr::GetDeviceSdr::new(None, current_id)); + + match next_record { + Ok(record) => { + if recoverable_errors > 0 { + log::warn!( + "Skipped {} recoverable errors before processing record 0x{:04X}.", + recoverable_errors, + current_id.value() + ); + } + + let next_record_id = record.next_entry; + + if next_record_id == current_id { + log::error!("Got duplicate SDR record IDs! Stopping iteration."); + self.next_id.take(); + return None; + } + + self.next_id = Some(next_record_id); + return Some(record.record); + } + Err(IpmiError::ParsingFailed { + error: ParseResponseError::Parse((e, next_record_id)), + .. + }) => { + recoverable_errors += 1; + if recoverable_errors > MAX_RECOVERABLE_ERRORS { + log::error!( + "Exceeded maximum recoverable errors ({}). Stopping iteration.", + MAX_RECOVERABLE_ERRORS + ); + self.next_id.take(); + return None; + } + + log::debug!( + "Recoverable error while parsing SDR record 0x{:04X}: {e:?}. Skipping to next.", + current_id.value() + ); + self.next_id = Some(next_record_id); + continue; // skip the current one + } + Err(e) => { + log::error!( + "Unrecoverable error while parsing SDR record 0x{:04X}: {e:?}", + current_id.value() + ); + self.next_id.take(); + return None; + } + } + } + + if recoverable_errors > 0 { + log::warn!( + "Iteration completed with {} recoverable errors.", + recoverable_errors + ); } - value + None } }