Skip to content

Commit

Permalink
Error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Virgiel committed Jul 3, 2023
1 parent 8940433 commit 20691a7
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
12 changes: 7 additions & 5 deletions crates/cornucopia/src/codegen/vfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::{
path::{Path, PathBuf},
};

use crate::error::PersistError;

/// In memory storage of file
/// Can only fail while persisting
pub struct Vfs {
Expand All @@ -22,23 +24,23 @@ impl Vfs {
}

/// Materialize on real file system, overwrite existing directory if any
pub fn persist(self, destination: impl AsRef<Path>) -> std::io::Result<()> {
pub fn persist(self, destination: impl AsRef<Path>) -> Result<(), PersistError> {
let destination = destination.as_ref();
// First write in a temporary directory to prevent leaving the destination in a bad state
let tmp = tempfile::tempdir()?;
let tmp = tempfile::tempdir().map_err(PersistError::wrap("tempfile"))?;
for (path, content) in self.fs {
let path = tmp.path().join(path);
let parent = path
.parent()
.expect("Must at least has 'destination' as parent");
std::fs::create_dir_all(parent).ok(); // Might already exist
std::fs::write(path, content)?;
std::fs::write(&path, content).map_err(PersistError::wrap(path))?;
}
// Swap destination and tmp as atomically as possible
// TODO is it possible to do this atomically for some platform ?
std::fs::remove_dir_all(destination).ok(); // Might not exist
std::fs::create_dir_all(destination)?;
std::fs::rename(tmp.into_path(), destination)?;
std::fs::create_dir_all(destination).map_err(PersistError::wrap(destination))?;
std::fs::rename(tmp.into_path(), destination).map_err(PersistError::wrap(destination))?;
Ok(())
}
}
17 changes: 13 additions & 4 deletions crates/cornucopia/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub enum Error {
PrepareQueries(#[from] crate::prepare_queries::error::Error),
/// An error while reading PostgreSQL schema files.
LoadSchema(#[from] crate::load_schema::error::Error),
/// An error while trying to write the generated code to its destination file.
WriteCodeGenFile(#[from] WriteOutputError),
/// An error while trying to write the generated crate to its destination.
PersistCrate(#[from] PersistError),
}

impl Error {
Expand All @@ -39,8 +39,17 @@ impl Error {
}

#[derive(Debug, ThisError, Diagnostic)]
#[error("Could not write your queries to destination file `{file_path}`: ({err})")]
pub struct WriteOutputError {
#[error("Could not perform IO on file `{file_path}`: ({err})")]
pub struct PersistError {
pub(crate) file_path: PathBuf,
pub(crate) err: std::io::Error,
}

impl PersistError {
pub fn wrap(path: impl Into<PathBuf>) -> impl FnOnce(std::io::Error) -> PersistError {
|err| PersistError {
file_path: path.into(),
err,
}
}
}
4 changes: 2 additions & 2 deletions crates/cornucopia/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub fn gen_live<P: AsRef<Path>>(
settings,
);
// Write
generated.persist(destination).expect("TODO error handling");
generated.persist(destination)?;

Ok(())
}
Expand Down Expand Up @@ -92,7 +92,7 @@ pub fn gen_managed<P: AsRef<Path>>(
);
container::cleanup(podman)?;
// Write
generated.persist(destination).expect("TODO error handling");
generated.persist(destination)?;

Ok(())
}
Expand Down

0 comments on commit 20691a7

Please sign in to comment.