Skip to content

Commit 0651942

Browse files
committed
CLI - Don't silent fail when failing to read migration directory
The `migrations_directories` from `migration_internals` silently dropped failing to read the migrations directory by calling `into_iter()` on the result of `read_dir()`. The error is now propagated as an extra `Result` level on these functions, because keeping the same signature would require putting these errors inside the iterator, which would have required adding a dependency on `either` for the implementation to not be unreasonable.
1 parent 83ffef7 commit 0651942

3 files changed

Lines changed: 25 additions & 29 deletions

File tree

diesel_migrations/migrations_internals/src/lib.rs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -86,26 +86,20 @@ pub fn file_names(path: &Path) -> Result<Vec<String>, std::io::Error> {
8686

8787
pub fn migrations_directories<'a>(
8888
path: &'a Path,
89-
) -> impl Iterator<Item = Result<DirEntry, std::io::Error>> + 'a {
90-
path.read_dir()
91-
.into_iter()
92-
.flatten()
93-
.filter_map(move |entry| {
94-
let entry = match entry {
95-
Ok(e) => e,
96-
Err(e) => return Some(Err(e)),
97-
};
98-
let metadata = match entry.metadata() {
99-
Ok(m) => m,
100-
Err(e) => return Some(Err(e)),
101-
};
102-
if metadata.is_file() {
103-
return None;
104-
}
105-
if entry.file_name().to_string_lossy().starts_with('.') {
106-
None
107-
} else {
108-
Some(Ok(entry))
109-
}
110-
})
89+
) -> Result<impl Iterator<Item = Result<DirEntry, std::io::Error>> + 'a, std::io::Error> {
90+
Ok(path.read_dir()?.into_iter().filter_map(|entry_res| {
91+
entry_res
92+
.and_then(|entry| {
93+
Ok(
94+
if entry.metadata()?.is_file()
95+
|| entry.file_name().to_string_lossy().starts_with('.')
96+
{
97+
None
98+
} else {
99+
Some(entry)
100+
},
101+
)
102+
})
103+
.transpose()
104+
}))
111105
}

diesel_migrations/migrations_macros/src/embed_migrations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn expand(path: String) -> proc_macro2::TokenStream {
2929
fn migration_literals_from_path(
3030
path: &Path,
3131
) -> Result<Vec<proc_macro2::TokenStream>, Box<dyn Error>> {
32-
let mut migrations = migrations_directories(path).collect::<Result<Vec<_>, _>>()?;
32+
let mut migrations = migrations_directories(path)?.collect::<Result<Vec<_>, _>>()?;
3333

3434
migrations.sort_by_key(DirEntry::path);
3535

diesel_migrations/src/file_based_migrations.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl FileBasedMigrations {
8686
///
8787
/// This methods fails if the path passed as argument is no valid migration directory
8888
pub fn from_path(path: impl AsRef<Path>) -> Result<Self, MigrationError> {
89-
for dir in migrations_directories(path.as_ref()) {
89+
for dir in migrations_directories(path.as_ref())? {
9090
let path = dir?.path();
9191
if !migrations_internals::valid_sql_migration_directory(&path) {
9292
return Err(MigrationError::UnknownMigrationFormat(path));
@@ -134,19 +134,19 @@ fn search_for_migrations_directory(path: &Path) -> Result<PathBuf, MigrationErro
134134

135135
fn migrations_directories<'a>(
136136
path: &'a Path,
137-
) -> impl Iterator<Item = Result<DirEntry, MigrationError>> + 'a {
138-
migrations_internals::migrations_directories(path).map(move |e| e.map_err(Into::into))
137+
) -> Result<impl Iterator<Item = Result<DirEntry, MigrationError>> + 'a, MigrationError> {
138+
Ok(migrations_internals::migrations_directories(path)?.map(move |e| e.map_err(Into::into)))
139139
}
140140

141141
fn migrations_in_directory<'a, DB: Backend>(
142142
path: &'a Path,
143-
) -> impl Iterator<Item = Result<SqlFileMigration, MigrationError>> + 'a {
144-
migrations_directories(path).map(|entry| SqlFileMigration::from_path(&entry?.path()))
143+
) -> Result<impl Iterator<Item = Result<SqlFileMigration, MigrationError>> + 'a, MigrationError> {
144+
Ok(migrations_directories(path)?.map(|entry| SqlFileMigration::from_path(&entry?.path())))
145145
}
146146

147147
impl<DB: Backend> MigrationSource<DB> for FileBasedMigrations {
148148
fn migrations(&self) -> migration::Result<Vec<Box<dyn Migration<DB>>>> {
149-
migrations_in_directory::<DB>(&self.base_path)
149+
migrations_in_directory::<DB>(&self.base_path)?
150150
.map(|r| Ok(Box::new(r?) as Box<dyn Migration<DB>>))
151151
.collect()
152152
}
@@ -355,6 +355,7 @@ mod tests {
355355
fs::File::create(&file_path).unwrap();
356356

357357
let migrations = migrations_in_directory::<Backend>(&migrations_path)
358+
.unwrap()
358359
.collect::<Result<Vec<_>, _>>()
359360
.unwrap();
360361

@@ -372,6 +373,7 @@ mod tests {
372373
fs::create_dir(&dot_path).unwrap();
373374

374375
let migrations = migrations_in_directory::<Backend>(&migrations_path)
376+
.unwrap()
375377
.collect::<Result<Vec<_>, _>>()
376378
.unwrap();
377379

0 commit comments

Comments
 (0)