Skip to main content

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(#[automatically_derived]
impl ::core::fmt::Debug for MigrationError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            MigrationError::MigrationDirectoryNotFound(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "MigrationDirectoryNotFound", &__self_0),
            MigrationError::UnknownMigrationFormat(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "UnknownMigrationFormat", &__self_0),
            MigrationError::IoError(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "IoError", &__self_0),
            MigrationError::UnknownMigrationVersion(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "UnknownMigrationVersion", &__self_0),
            MigrationError::NoMigrationRun =>
                ::core::fmt::Formatter::write_str(f, "NoMigrationRun"),
            MigrationError::NoMigrationRevertFile =>
                ::core::fmt::Formatter::write_str(f, "NoMigrationRevertFile"),
        }
    }
}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) => f.write_fmt(format_args!("Unable to find migrations directory in {0:?} or any parent directories.",
        p))write!(
38                f,
39                "Unable to find migrations directory in {p:?} or any parent directories."
40            ),
41            MigrationError::UnknownMigrationFormat(_) => f.write_fmt(format_args!("Invalid migration directory: the directory\'s name should be <timestamp>_<name_of_migration>, and it should contain up.sql and optionally down.sql."))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) => f.write_fmt(format_args!("{0}", error))write!(f, "{error}"),
48            MigrationError::UnknownMigrationVersion(ref version) => f.write_fmt(format_args!("Unable to find migration version {0} to revert in the migrations directory.",
        version))write!(
49                f,
50                "Unable to find migration version {version} to revert in the migrations directory."
51            ),
52            MigrationError::NoMigrationRun => f.write_fmt(format_args!("No migrations have been run. Did you forget `diesel migration run`?"))write!(
53                f,
54                "No migrations have been run. Did you forget `diesel migration run`?"
55            ),
56            MigrationError::NoMigrationRevertFile => {
57                f.write_fmt(format_args!("Missing `down.sql` file to revert migration"))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(#[automatically_derived]
#[allow(clippy::enum_variant_names)]
impl ::core::fmt::Debug for RunMigrationsError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            RunMigrationsError::MigrationError(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "MigrationError", __self_0, &__self_1),
            RunMigrationsError::QueryError(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "QueryError", __self_0, &__self_1),
            RunMigrationsError::EmptyMigration(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "EmptyMigration", &__self_0),
        }
    }
}Debug, #[automatically_derived]
#[allow(clippy::enum_variant_names)]
impl ::core::cmp::PartialEq for RunMigrationsError {
    #[inline]
    fn eq(&self, other: &RunMigrationsError) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (RunMigrationsError::MigrationError(__self_0, __self_1),
                    RunMigrationsError::MigrationError(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (RunMigrationsError::QueryError(__self_0, __self_1),
                    RunMigrationsError::QueryError(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (RunMigrationsError::EmptyMigration(__self_0),
                    RunMigrationsError::EmptyMigration(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}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                f.write_fmt(format_args!("Failed to run {0} with: {1}", v, err))write!(f, "Failed to run {v} with: {err}")
105            }
106            RunMigrationsError::QueryError(v, err) => {
107                f.write_fmt(format_args!("Failed to run {0} with: {1}", v, err))write!(f, "Failed to run {v} with: {err}")?;
108
109                if let diesel::result::Error::DatabaseError(_, error_info) = err {
110                    let message = error_info.message();
111                    if message.ends_with("cannot run inside a transaction block") {
112                        f.write_fmt(format_args!(" (see https://docs.diesel.rs/{0}.x/diesel_migrations/struct.FileBasedMigrations.html#transactions)",
        "2.3.2".rsplit_once('.').expect("We get a semver version here").0))write!(
113                            f,
114                            " (see https://docs.diesel.rs/{}.x/diesel_migrations/struct.FileBasedMigrations.html#transactions)",
115                            env!("CARGO_PKG_VERSION")
116                                .rsplit_once('.')
117                                .expect("We get a semver version here")
118                                .0
119                        )?;
120                    }
121                }
122
123                Ok(())
124            }
125            RunMigrationsError::EmptyMigration(v) => f.write_fmt(format_args!("Failed to run {0} with: Attempted to run an empty migration.",
        v))write!(
126                f,
127                "Failed to run {v} with: Attempted to run an empty migration."
128            ),
129        }
130    }
131}