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
136impl StdError for Error {}