martin_core/tiles/postgres/
errors.rs1use std::io;
4use std::path::PathBuf;
5
6use deadpool_postgres::tokio_postgres::Error as TokioPostgresError;
7use deadpool_postgres::tokio_postgres::config::SslMode;
8use deadpool_postgres::{BuildError, PoolError};
9use martin_tile_utils::TileCoord;
10use semver::Version;
11
12use crate::tiles::UrlQuery;
13use crate::tiles::postgres::RedactedConnectionString;
14use crate::tiles::postgres::utils::query_to_json;
15
16pub type PostgresResult<T> = Result<T, PostgresError>;
18
19#[non_exhaustive]
21#[derive(thiserror::Error, Debug)]
22pub enum PostgresError {
23 #[error("Filter '{0}' is not valid CQL2: {1}")]
25 InvalidFilter(String, String),
26
27 #[error("Cannot load platform root certificates: {0:?}")]
29 CannotLoadRoots(Vec<rustls_native_certs::Error>),
30
31 #[error("Cannot open certificate file {1}: {0}")]
33 CannotOpenCert(#[source] io::Error, PathBuf),
34
35 #[error("Cannot parse certificate file {1}: {0}")]
37 CannotParseCert(#[source] io::Error, PathBuf),
38
39 #[error("Unable to parse PEM RSA key file {0}")]
41 InvalidPrivateKey(PathBuf),
42
43 #[error("Unable to use client certificate pair {cert} / {key}: {source}")]
45 CannotUseClientKey {
46 #[source]
48 source: rustls::Error,
49 cert: PathBuf,
51 key: PathBuf,
53 },
54
55 #[error(transparent)]
57 RustlsError(#[from] rustls::Error),
58
59 #[error(transparent)]
61 CannotBuildTlsVerifier(#[from] rustls::client::VerifierBuilderError),
62
63 #[error("Unknown SSL mode: {0:?}")]
65 UnknownSslMode(SslMode),
66
67 #[error("Postgres error while {1}: {0}")]
69 PostgresError(#[source] TokioPostgresError, &'static str),
70
71 #[error("Unable to build a Postgres connection pool {1}: {0}")]
73 PostgresPoolBuildError(#[source] BuildError, String),
74
75 #[error("Unable to get a Postgres connection from the pool {1}: {0}")]
77 PostgresPoolConnError(#[source] PoolError, String),
78
79 #[error("Unable to parse connection string {1}: {0}")]
81 BadConnectionString(#[source] TokioPostgresError, RedactedConnectionString),
82
83 #[error("Unable to parse PostGIS version {1}: {0}")]
85 BadPostgisVersion(#[source] semver::Error, String),
86
87 #[error("Unable to parse PostgreSQL version {version_num}")]
89 BadPostgresVersion {
90 version_num: i32,
92 },
93
94 #[error("PostGIS version {current} is too old, minimum required is {minimum}")]
96 PostgisTooOld {
97 current: Version,
99 minimum: Version,
101 },
102
103 #[error("PostgreSQL version {current} is too old, minimum required is {minimum}")]
105 PostgresqlTooOld {
106 current: Version,
108 minimum: Version,
110 },
111
112 #[error("Error preparing a query for the tile '{source_id}' ({signature}): {query} {source}")]
114 PrepareQueryError {
115 #[source]
117 source: TokioPostgresError,
118 source_id: String,
120 signature: String,
122 query: String,
124 },
125
126 #[error(r"Unable to get tile {2:#} from {1}: {0}")]
128 GetTileError(#[source] TokioPostgresError, String, TileCoord),
129
130 #[error(r"Unable to get tile {2:#} with {json_query:?} params from {1}: {0}", json_query=query_to_json(.3.as_ref()))]
132 GetTileWithQueryError(
133 #[source] TokioPostgresError,
134 String,
135 TileCoord,
136 Option<UrlQuery>,
137 ),
138}
139
140impl crate::Classify for PostgresError {
141 fn kind(&self) -> crate::ErrorKind {
142 use crate::ErrorKind::{Internal, Unavailable};
143 match self {
144 Self::PostgresPoolConnError(..) => Unavailable,
145 Self::InvalidFilter(..)
146 | Self::CannotLoadRoots(_)
147 | Self::CannotOpenCert(..)
148 | Self::CannotParseCert(..)
149 | Self::InvalidPrivateKey(_)
150 | Self::CannotUseClientKey { .. }
151 | Self::RustlsError(_)
152 | Self::CannotBuildTlsVerifier(_)
153 | Self::UnknownSslMode(_)
154 | Self::PostgresError(..)
155 | Self::PostgresPoolBuildError(..)
156 | Self::BadConnectionString(..)
157 | Self::BadPostgisVersion(..)
158 | Self::BadPostgresVersion { .. }
159 | Self::PostgisTooOld { .. }
160 | Self::PostgresqlTooOld { .. }
161 | Self::PrepareQueryError { .. }
162 | Self::GetTileError(..)
163 | Self::GetTileWithQueryError(..) => Internal,
164 }
165 }
166}