From b04dd8b601cafb5a49667333a1454884d13eb2f9 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 18 Apr 2026 18:18:57 -0400 Subject: [PATCH] fix: demote path-not-exists validation errors to debug The /image cross-library fallback tries the resolved library first and falls back to any library holding the rel_path. The first attempt emitted error-level noise on every grid tile in union mode. Split the validation error so only traversal attempts log at error; missing-file cases log at debug. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/files.rs | 62 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/src/files.rs b/src/files.rs index d70d2ce..fdeec9f 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,6 +1,6 @@ use ::anyhow; use actix::{Handler, Message}; -use anyhow::{Context, anyhow}; +use anyhow::Context; use std::collections::HashSet; use std::fmt::Debug; use std::fs::read_dir; @@ -1024,33 +1024,58 @@ pub fn is_valid_full_path + Debug + AsRef>( match is_path_above_base_dir(base, &mut path, new_file) { Ok(path) => Some(path), - Err(e) => { + Err(PathValidationError::DoesNotExist(p)) => { + debug!("Path does not exist under base {:?}: {:?}", base, p); + None + } + Err(PathValidationError::AboveBase(p)) => { + error!("Path above base directory {:?}: {:?}", base, p); + None + } + Err(PathValidationError::Other(e)) => { error!("{}", e); None } } } +#[derive(Debug)] +enum PathValidationError { + DoesNotExist(PathBuf), + AboveBase(PathBuf), + Other(anyhow::Error), +} + +impl std::fmt::Display for PathValidationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PathValidationError::DoesNotExist(p) => write!(f, "Path does not exist: {:?}", p), + PathValidationError::AboveBase(p) => write!(f, "Path above base directory: {:?}", p), + PathValidationError::Other(e) => write!(f, "{}", e), + } + } +} + fn is_path_above_base_dir + Debug>( base: P, full_path: &mut PathBuf, new_file: bool, -) -> anyhow::Result { - full_path - .absolutize() - .with_context(|| format!("Unable to resolve absolute path: {:?}", full_path)) - .map_or_else( - |e| Err(anyhow!(e)), - |p| { - if p.starts_with(base) && (new_file || p.exists()) { - Ok(p.into_owned()) - } else if !p.exists() { - Err(anyhow!("Path does not exist: {:?}", p)) - } else { - Err(anyhow!("Path above base directory")) - } - }, - ) +) -> Result { + match full_path.absolutize() { + Err(e) => Err(PathValidationError::Other( + anyhow::Error::new(e) + .context(format!("Unable to resolve absolute path: {:?}", full_path)), + )), + Ok(p) => { + if p.starts_with(base) && (new_file || p.exists()) { + Ok(p.into_owned()) + } else if !p.exists() { + Err(PathValidationError::DoesNotExist(p.into_owned())) + } else { + Err(PathValidationError::AboveBase(p.into_owned())) + } + } + } } /// Handler for GPS summary endpoint @@ -1289,6 +1314,7 @@ impl Handler for StreamActor { mod tests { use super::*; use crate::database::DbError; + use ::anyhow::anyhow; use std::collections::HashMap; use std::env; use std::fs::File;