movine/
errors.rs

1use libsqlite3_sys::Error as SqliteLibError;
2use libsqlite3_sys::ErrorCode as SqliteLibErrorCode;
3use postgres::error::Error as PostgresError;
4use rusqlite::Error as SqliteError;
5use std::error::Error as StdError;
6use std::fmt;
7use std::io;
8use toml::de::Error as TomlError;
9
10pub type Result<T> = std::result::Result<T, Error>;
11
12pub enum Error {
13    ConfigNotFound,
14    PgParamError {
15        user: bool,
16        password: bool,
17        database: bool,
18        host: bool,
19        port: bool,
20    },
21    SqliteParamError {
22        file: bool,
23    },
24    BadMigration,
25    Unknown,
26    AdaptorNotFound,
27    MigrationDirNotFound,
28    DirtyMigrations,
29    DivergentMigration,
30    UnrollbackableMigration,
31    IoError(io::Error),
32    TomlError(TomlError),
33    PgError(PostgresError),
34    SqliteError(SqliteError),
35    Envy(envy::Error),
36    #[cfg(feature = "with-native-tls")]
37    NativeTlsError(native_tls::Error),
38    #[cfg(feature = "with-rustls")]
39    RustlsError(rustls::TLSError),
40    #[cfg(feature = "with-rustls")]
41    RustlsPemfileError,
42}
43
44impl fmt::Debug for Error {
45    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46        use Error::*;
47        match self {
48            ConfigNotFound => write!(f, "`movine.toml` config file not found and no environment variables were found."),
49            BadMigration => write!(f, "Error parsing migrations."),
50            Unknown => write!(f, "Unknown error occurred"),
51            AdaptorNotFound => write!(f, "Could not find adaptor"),
52            MigrationDirNotFound => write!(f, "Could not find migration directory"),
53            DirtyMigrations => write!(f, "More recent migrations exist in the database than the pending migrations. This is an error when run with --strict"),
54            DivergentMigration => write!(f, "Divergent migration found. Run with --ignore-divergent to ignore divergent migrations."),
55            UnrollbackableMigration => write!(f, "Can't rollback one of the migrations in the list. Consider changing your parameters or adding a `down.sql` migration."),
56            IoError(e) => write!(f, "IO Error: {}", e),
57            TomlError(e) => write!(f, "Unable to read config file: {}", e),
58            PgError(e) => write!(f, "Error in Postgres: {}", e),
59            SqliteError(e) => {
60                match e {
61                    rusqlite::Error::SqliteFailure(SqliteLibError { code: SqliteLibErrorCode::APIMisuse, .. }, _) => {
62                        write!(f, "Error in Sqlite: {}.", e)?;
63                        write!(f, "\nThis is likely due to an invalid SQL statement, such as an empty UP or DOWN migration.")
64                    }
65                    _ => write!(f, "Error in Sqlite: {}", e),
66                }
67            }
68            Envy(e) => write!(f, "Error in loading environment variables: {}", e),
69            #[cfg(feature = "with-native-tls")]
70            NativeTlsError(e) => write!(f, "Error in TLS: {}", e),
71            #[cfg(feature = "with-rustls")]
72            RustlsError(e) => write!(f, "Error in TLS: {}", e),
73            #[cfg(feature = "with-rustls")]
74            RustlsPemfileError => write!(f, "Error in TLS: could not add PEM file to store"),
75            SqliteParamError { .. } => write!(f, "Unable to load Sqlite params. Make sure you have `file` defined in your `movine.toml` or SQLITE_FILE defined as an environment variable"),
76            PgParamError {
77                user, password, database, host, port
78            } => {
79                write!(f, "Unable to load Postgres params. Please ensure you have the following defined:\nUser: {}\nPassword: {}\nDatabase: {}\nHost: {}\nPort: {}",
80                    user, password, database, host, port)
81            }
82        }
83    }
84}
85
86impl fmt::Display for Error {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        write!(f, "{:?}", self)
89    }
90}
91
92impl From<io::Error> for Error {
93    fn from(error: io::Error) -> Self {
94        Error::IoError(error)
95    }
96}
97
98impl From<TomlError> for Error {
99    fn from(error: TomlError) -> Self {
100        Error::TomlError(error)
101    }
102}
103
104impl From<PostgresError> for Error {
105    fn from(error: PostgresError) -> Self {
106        Error::PgError(error)
107    }
108}
109
110impl From<SqliteError> for Error {
111    fn from(error: SqliteError) -> Self {
112        Error::SqliteError(error)
113    }
114}
115
116impl From<envy::Error> for Error {
117    fn from(error: envy::Error) -> Self {
118        Error::Envy(error)
119    }
120}
121
122#[cfg(feature = "with-native-tls")]
123impl From<native_tls::Error> for Error {
124    fn from(error: native_tls::Error) -> Self {
125        Error::NativeTlsError(error)
126    }
127}
128
129#[cfg(feature = "with-rustls")]
130impl From<rustls::TLSError> for Error {
131    fn from(error: rustls::TLSError) -> Self {
132        Error::RustlsError(error)
133    }
134}
135
136// Implements std::Error for ease of use outside of Movine
137impl StdError for Error {}