fix: remaining unwrap panics and new bugs discovered during audit

- email worker: replace Mailbox::parse().unwrap() with match to
  handle invalid recipient addresses gracefully
- metrics middleware: RwLock poison recovery on read/write locks
  to prevent panic on thread panic
- access key: SystemTime::now() unwrap_or_default instead of unwrap
  for clock-before-epoch edge case
- chpc: NaiveDateTime and_hms_opt unwrap_or MIN/MAX fallbacks
- push notification: second code path fixed for let-chain unwrap
- ai_streaming: constant UUID parse use expect() instead of unwrap
This commit is contained in:
ZhenYi 2026-04-27 11:30:01 +08:00
parent df42af2ed0
commit f36f08e3c4
4 changed files with 16 additions and 12 deletions

View File

@ -64,16 +64,20 @@ impl AppEmail {
tokio::spawn(async move {
while let Some(msg) = rx.recv().await {
if !EMAIL_REGEX.is_match(&msg.clone().to) {
counter!("email_validation_skipped_total").increment(1);
continue;
}
let recipient: Mailbox = match msg.to.parse() {
Ok(addr) => addr,
Err(_) => {
counter!("email_validation_skipped_total").increment(1);
tracing::warn!(to = %msg.to, "Invalid recipient address");
continue;
}
};
let email = match lettre::Message::builder()
.from(from.clone())
.to(msg.clone().to.parse().unwrap())
.subject(msg.clone().subject)
.body(msg.clone().body)
.to(recipient)
.subject(msg.subject)
.body(msg.body)
{
Ok(e) => e,
Err(_) => {

View File

@ -37,7 +37,7 @@ impl HttpMetrics {
/// Increment the counter for a specific HTTP endpoint (method + path).
pub fn incr_endpoint(&self, method: &str, path: &str) {
let key = format!("{} {}", method, path);
let mut map = self.endpoint_counts.write().unwrap();
let mut map = self.endpoint_counts.write().unwrap_or_else(|e| e.into_inner());
let counter = map.entry(key).or_insert_with(|| AtomicU64::new(0));
counter.fetch_add(1, Ordering::Relaxed);
}
@ -52,7 +52,7 @@ impl HttpMetrics {
m.insert("http_requests_5xx".into(), serde_json::json!(self.status_5xx.load(Ordering::Relaxed)));
// Per-endpoint counters
let map = self.endpoint_counts.read().unwrap();
let map = self.endpoint_counts.read().unwrap_or_else(|e| e.into_inner());
for (key, counter) in map.iter() {
// Sanitize key for use as metric name: replace spaces and slashes with underscores
let sanitized = key.replace([' ', '/'], "_").to_lowercase();

View File

@ -214,7 +214,7 @@ impl AppService {
use std::time::{SystemTime, UNIX_EPOCH};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.unwrap_or_default()
.as_nanos();
let chars: Vec<char> = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
.chars()

View File

@ -78,8 +78,8 @@ impl AppService {
return Ok(response);
}
let start_dt = start_date.and_hms_opt(0, 0, 0).unwrap();
let end_dt = end_date.and_hms_opt(23, 59, 59).unwrap();
let start_dt = start_date.and_hms_opt(0, 0, 0).unwrap_or(chrono::NaiveDateTime::MIN);
let end_dt = end_date.and_hms_opt(23, 59, 59).unwrap_or(chrono::NaiveDateTime::MAX);
let commits: Vec<repo_commit::Model> = repo_commit::Entity::find()
.filter(repo_commit::Column::AuthorEmail.is_in(emails.clone()))