diesel_migrations/
errors.rs

1//! Error types that represent migration errors.
2//! These are split into multiple segments, depending on
3//! where in the migration process an error occurs.
4
5use std::error::Error;
6use std::path::PathBuf;
7use std::{fmt, io};
8
9use diesel::migration::MigrationVersion;
10
11use crate::file_based_migrations::DieselMigrationName;
12
13/// Errors that occur while preparing to run migrations
14#[derive(Debug)]
15#[non_exhaustive]
16pub enum MigrationError {
17    /// The migration directory wasn't found
18    MigrationDirectoryNotFound(PathBuf),
19    /// Provided migration was in an unknown format
20    UnknownMigrationFormat(PathBuf),
21    /// General system IO error
22    IoError(io::Error),
23    /// Provided migration had an incompatible version number
24    UnknownMigrationVersion(MigrationVersion<'static>),
25    /// No migrations had to be/ could be run
26    NoMigrationRun,
27    /// `down.sql` file is missing, and you're asking for a `revert`
28    /// or `redo`
29    NoMigrationRevertFile,
30}
31
32impl Error for MigrationError {}
33
34impl fmt::Display for MigrationError {
35    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
36        match *self {
37            MigrationError::MigrationDirectoryNotFound(ref p) => write!(
38                f,
39                "Unable to find migrations directory in {p:?} or any parent directories."
40            ),
41            MigrationError::UnknownMigrationFormat(_) => write!(
42                f,
43                "Invalid migration directory: the directory's name should be \
44                 <timestamp>_<name_of_migration>, and it should contain up.sql and \
45                 optionally down.sql."
46            ),
47            MigrationError::IoError(ref error) => write!(f, "{error}"),
48            MigrationError::UnknownMigrationVersion(ref version) => write!(
49                f,
50                "Unable to find migration version {version} to revert in the migrations directory."
51            ),
52            MigrationError::NoMigrationRun => write!(
53                f,
54                "No migrations have been run. Did you forget `diesel migration run`?"
55            ),
56            MigrationError::NoMigrationRevertFile => {
57                write!(f, "Missing `down.sql` file to revert migration")
58            }
59        }
60    }
61}
62
63impl PartialEq for MigrationError {
64    fn eq(&self, other: &Self) -> bool {
65        match (self, other) {
66            (
67                &MigrationError::MigrationDirectoryNotFound(_),
68                &MigrationError::MigrationDirectoryNotFound(_),
69            ) => true,
70            (
71                MigrationError::UnknownMigrationFormat(p1),
72                MigrationError::UnknownMigrationFormat(p2),
73            ) => p1 == p2,
74            _ => false,
75        }
76    }
77}
78
79impl From<io::Error> for MigrationError {
80    fn from(e: io::Error) -> Self {
81        MigrationError::IoError(e)
82    }
83}
84
85/// Errors that occur while running migrations
86#[derive(Debug, PartialEq)]
87#[allow(clippy::enum_variant_names)]
88#[non_exhaustive]
89pub enum RunMigrationsError {
90    /// A general migration error occurred
91    MigrationError(DieselMigrationName, MigrationError),
92    /// The provided migration included an invalid query
93    QueryError(DieselMigrationName, diesel::result::Error),
94    /// The provided migration was empty
95    EmptyMigration(DieselMigrationName),
96}
97
98impl Error for RunMigrationsError {}
99
100impl fmt::Display for RunMigrationsError {
101    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
102        match self {
103            RunMigrationsError::MigrationError(v, err) => {
104                write!(f, "Failed to run {v} with: {err}")
105            }
106            RunMigrationsError::QueryError(v, err) => {
107                write!(f, "Failed to run {v} with: {err}")
108            }
109            RunMigrationsError::EmptyMigration(v) => write!(
110                f,
111                "Failed to run {v} with: Attempted to run an empty migration."
112            ),
113        }
114    }
115}