Line data Source code
1 : use http::StatusCode;
2 : use http::header::HeaderName;
3 :
4 : use crate::auth::ComputeUserInfoParseError;
5 : use crate::error::{ErrorKind, ReportableError, UserFacingError};
6 : use crate::http::ReadBodyError;
7 :
8 : pub trait HttpCodeError {
9 : fn get_http_status_code(&self) -> StatusCode;
10 : }
11 :
12 : #[derive(Debug, thiserror::Error)]
13 : pub(crate) enum ConnInfoError {
14 : #[error("invalid header: {0}")]
15 : InvalidHeader(&'static HeaderName),
16 : #[error("invalid connection string: {0}")]
17 : UrlParseError(#[from] url::ParseError),
18 : #[error("incorrect scheme")]
19 : IncorrectScheme,
20 : #[error("missing database name")]
21 : MissingDbName,
22 : #[error("invalid database name")]
23 : InvalidDbName,
24 : #[error("missing username")]
25 : MissingUsername,
26 : #[error("invalid username: {0}")]
27 : InvalidUsername(#[from] std::string::FromUtf8Error),
28 : #[error("missing authentication credentials: {0}")]
29 : MissingCredentials(Credentials),
30 : #[error("missing hostname")]
31 : MissingHostname,
32 : #[error("invalid hostname: {0}")]
33 : InvalidEndpoint(#[from] ComputeUserInfoParseError),
34 : }
35 :
36 : #[derive(Debug, thiserror::Error)]
37 : pub(crate) enum Credentials {
38 : #[error("required password")]
39 : Password,
40 : #[error("required authorization bearer token in JWT format")]
41 : BearerJwt,
42 : }
43 :
44 : impl ReportableError for ConnInfoError {
45 0 : fn get_error_kind(&self) -> ErrorKind {
46 0 : ErrorKind::User
47 0 : }
48 : }
49 :
50 : impl UserFacingError for ConnInfoError {
51 0 : fn to_string_client(&self) -> String {
52 0 : self.to_string()
53 0 : }
54 : }
55 :
56 : #[derive(Debug, thiserror::Error)]
57 : pub(crate) enum ReadPayloadError {
58 : #[error("could not read the HTTP request body: {0}")]
59 : Read(#[from] hyper::Error),
60 : #[error("request is too large (max is {limit} bytes)")]
61 : BodyTooLarge { limit: usize },
62 : #[error("could not parse the HTTP request body: {0}")]
63 : Parse(#[from] serde_json::Error),
64 : }
65 :
66 : impl From<ReadBodyError<hyper::Error>> for ReadPayloadError {
67 0 : fn from(value: ReadBodyError<hyper::Error>) -> Self {
68 0 : match value {
69 0 : ReadBodyError::BodyTooLarge { limit } => Self::BodyTooLarge { limit },
70 0 : ReadBodyError::Read(e) => Self::Read(e),
71 : }
72 0 : }
73 : }
74 :
75 : impl ReportableError for ReadPayloadError {
76 0 : fn get_error_kind(&self) -> ErrorKind {
77 0 : match self {
78 0 : ReadPayloadError::Read(_) => ErrorKind::ClientDisconnect,
79 0 : ReadPayloadError::BodyTooLarge { .. } => ErrorKind::User,
80 0 : ReadPayloadError::Parse(_) => ErrorKind::User,
81 : }
82 0 : }
83 : }
84 :
85 : impl HttpCodeError for ReadPayloadError {
86 0 : fn get_http_status_code(&self) -> StatusCode {
87 0 : match self {
88 0 : ReadPayloadError::Read(_) => StatusCode::BAD_REQUEST,
89 0 : ReadPayloadError::BodyTooLarge { .. } => StatusCode::PAYLOAD_TOO_LARGE,
90 0 : ReadPayloadError::Parse(_) => StatusCode::BAD_REQUEST,
91 : }
92 0 : }
93 : }
|