diff --git a/crates/cdk-cli/src/main.rs b/crates/cdk-cli/src/main.rs index 01394a9e..3cc75141 100644 --- a/crates/cdk-cli/src/main.rs +++ b/crates/cdk-cli/src/main.rs @@ -131,6 +131,11 @@ async fn main() -> Result<()> { } }; + // Create work directory if it doesn't exist + if !work_dir.exists() { + fs::create_dir_all(&work_dir)?; + } + let localstore: Arc + Send + Sync> = match args.engine.as_str() { "sqlite" => { diff --git a/crates/cdk-redb/src/error.rs b/crates/cdk-redb/src/error.rs index 195e024b..2964280f 100644 --- a/crates/cdk-redb/src/error.rs +++ b/crates/cdk-redb/src/error.rs @@ -43,6 +43,9 @@ pub enum Error { /// CDK Error #[error(transparent)] CDK(#[from] cdk_common::error::Error), + /// IO Error + #[error(transparent)] + Io(#[from] std::io::Error), /// NUT00 Error #[error(transparent)] CDKNUT00(#[from] cdk_common::nuts::nut00::Error), diff --git a/crates/cdk-redb/src/wallet/mod.rs b/crates/cdk-redb/src/wallet/mod.rs index f25c712e..44c4cce0 100644 --- a/crates/cdk-redb/src/wallet/mod.rs +++ b/crates/cdk-redb/src/wallet/mod.rs @@ -58,6 +58,16 @@ impl WalletRedbDatabase { /// Create new [`WalletRedbDatabase`] pub fn new(path: &Path) -> Result { { + // Check if parent directory exists before attempting to create database + if let Some(parent) = path.parent() { + if !parent.exists() { + return Err(Error::Io(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("Parent directory does not exist: {:?}", parent), + ))); + } + } + let db = Arc::new(Database::create(path)?); let db_version: Option; @@ -156,6 +166,16 @@ impl WalletRedbDatabase { drop(db); } + // Check parent directory again for final database creation + if let Some(parent) = path.parent() { + if !parent.exists() { + return Err(Error::Io(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("Parent directory does not exist: {:?}", parent), + ))); + } + } + let mut db = Database::create(path)?; db.upgrade()?; diff --git a/crates/cdk-sqlite/src/common.rs b/crates/cdk-sqlite/src/common.rs index d00bfaf6..178f554e 100644 --- a/crates/cdk-sqlite/src/common.rs +++ b/crates/cdk-sqlite/src/common.rs @@ -47,6 +47,15 @@ impl DatabasePool for SqliteConnectionManager { _timeout: Duration, ) -> Result> { let conn = if let Some(path) = config.path.as_ref() { + // Check if parent directory exists before attempting to open database + let path_buf = PathBuf::from(path); + if let Some(parent) = path_buf.parent() { + if !parent.exists() { + return Err(pool::Error::Resource(rusqlite::Error::InvalidPath( + path_buf.clone(), + ))); + } + } Connection::open(path)? } else { Connection::open_in_memory()?