aws_smithy_http/endpoint/
error.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Errors related to endpoint resolution and validation
7
8use std::error::Error;
9use std::fmt;
10
11/// Endpoint resolution failed
12#[derive(Debug)]
13pub struct ResolveEndpointError {
14    message: String,
15    source: Option<Box<dyn Error + Send + Sync>>,
16}
17
18impl ResolveEndpointError {
19    /// Create an [`ResolveEndpointError`] with a message
20    pub fn message(message: impl Into<String>) -> Self {
21        Self {
22            message: message.into(),
23            source: None,
24        }
25    }
26
27    /// Add a source to the error
28    pub fn with_source(self, source: Option<Box<dyn Error + Send + Sync>>) -> Self {
29        Self { source, ..self }
30    }
31
32    /// Create a [`ResolveEndpointError`] from a message and a source
33    pub fn from_source(
34        message: impl Into<String>,
35        source: impl Into<Box<dyn Error + Send + Sync>>,
36    ) -> Self {
37        Self::message(message).with_source(Some(source.into()))
38    }
39}
40
41impl fmt::Display for ResolveEndpointError {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        write!(f, "{}", self.message)
44    }
45}
46
47impl Error for ResolveEndpointError {
48    fn source(&self) -> Option<&(dyn Error + 'static)> {
49        self.source.as_ref().map(|err| err.as_ref() as _)
50    }
51}
52
53#[derive(Debug)]
54pub(super) enum InvalidEndpointErrorKind {
55    EndpointMustHaveScheme,
56    FailedToConstructAuthority {
57        authority: String,
58        source: Box<dyn Error + Send + Sync + 'static>,
59    },
60    FailedToConstructUri {
61        source: Box<dyn Error + Send + Sync + 'static>,
62    },
63}
64
65/// An error that occurs when an endpoint is found to be invalid. This usually occurs due to an
66/// incomplete URI.
67#[derive(Debug)]
68pub struct InvalidEndpointError {
69    pub(super) kind: InvalidEndpointErrorKind,
70}
71
72impl InvalidEndpointError {
73    /// Construct a build error for a missing scheme
74    pub fn endpoint_must_have_scheme() -> Self {
75        Self {
76            kind: InvalidEndpointErrorKind::EndpointMustHaveScheme,
77        }
78    }
79
80    /// Construct a build error for an invalid authority
81    pub fn failed_to_construct_authority(
82        authority: impl Into<String>,
83        source: impl Into<Box<dyn Error + Send + Sync + 'static>>,
84    ) -> Self {
85        Self {
86            kind: InvalidEndpointErrorKind::FailedToConstructAuthority {
87                authority: authority.into(),
88                source: source.into(),
89            },
90        }
91    }
92
93    /// Construct a build error for an invalid URI
94    pub fn failed_to_construct_uri(
95        source: impl Into<Box<dyn Error + Send + Sync + 'static>>,
96    ) -> Self {
97        Self {
98            kind: InvalidEndpointErrorKind::FailedToConstructUri {
99                source: source.into(),
100            },
101        }
102    }
103}
104
105impl From<InvalidEndpointErrorKind> for InvalidEndpointError {
106    fn from(kind: InvalidEndpointErrorKind) -> Self {
107        Self { kind }
108    }
109}
110
111impl fmt::Display for InvalidEndpointError {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        use InvalidEndpointErrorKind as ErrorKind;
114        match &self.kind {
115            ErrorKind::EndpointMustHaveScheme => write!(f, "endpoint must contain a valid scheme"),
116            ErrorKind::FailedToConstructAuthority { authority, source: _ } => write!(
117                f,
118                "endpoint must contain a valid authority when combined with endpoint prefix: {authority}"
119            ),
120            ErrorKind::FailedToConstructUri { .. } => write!(f, "failed to construct URI"),
121        }
122    }
123}
124
125impl Error for InvalidEndpointError {
126    fn source(&self) -> Option<&(dyn Error + 'static)> {
127        use InvalidEndpointErrorKind as ErrorKind;
128        match &self.kind {
129            ErrorKind::FailedToConstructUri { source } => Some(source.as_ref()),
130            ErrorKind::FailedToConstructAuthority {
131                authority: _,
132                source,
133            } => Some(source.as_ref()),
134            ErrorKind::EndpointMustHaveScheme => None,
135        }
136    }
137}