Skip to main content

aws_sigv4/http_request/
error.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use http::header::{InvalidHeaderName, InvalidHeaderValue};
7use http::uri::InvalidUri;
8use std::error::Error;
9use std::fmt;
10
11#[derive(Debug)]
12enum SigningErrorKind {
13    FailedToCreateCanonicalRequest {
14        source: CanonicalRequestError,
15    },
16    UnsupportedIdentityType,
17    #[cfg(feature = "sign-eventstream")]
18    FailedToEncodeMessage {
19        source: aws_smithy_eventstream::error::Error,
20    },
21}
22
23/// Error signing request
24#[derive(Debug)]
25pub struct SigningError {
26    kind: SigningErrorKind,
27}
28
29impl SigningError {
30    pub(crate) fn unsupported_identity_type() -> Self {
31        Self {
32            kind: SigningErrorKind::UnsupportedIdentityType,
33        }
34    }
35
36    #[cfg(feature = "sign-eventstream")]
37    pub(crate) fn failed_to_encode_message(source: aws_smithy_eventstream::error::Error) -> Self {
38        Self {
39            kind: SigningErrorKind::FailedToEncodeMessage { source },
40        }
41    }
42}
43
44impl fmt::Display for SigningError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self.kind {
47            SigningErrorKind::FailedToCreateCanonicalRequest { .. } => {
48                write!(f, "failed to create canonical request")
49            }
50            SigningErrorKind::UnsupportedIdentityType => {
51                write!(f, "only 'AWS credentials' are supported for signing")
52            }
53            #[cfg(feature = "sign-eventstream")]
54            SigningErrorKind::FailedToEncodeMessage { .. } => {
55                write!(f, "failed to encode the event stream message to sign")
56            }
57        }
58    }
59}
60
61impl Error for SigningError {
62    fn source(&self) -> Option<&(dyn Error + 'static)> {
63        match &self.kind {
64            SigningErrorKind::FailedToCreateCanonicalRequest { source } => Some(source),
65            SigningErrorKind::UnsupportedIdentityType => None,
66            #[cfg(feature = "sign-eventstream")]
67            SigningErrorKind::FailedToEncodeMessage { source } => Some(source),
68        }
69    }
70}
71
72impl From<CanonicalRequestError> for SigningError {
73    fn from(source: CanonicalRequestError) -> Self {
74        Self {
75            kind: SigningErrorKind::FailedToCreateCanonicalRequest { source },
76        }
77    }
78}
79
80#[derive(Debug)]
81enum CanonicalRequestErrorKind {
82    InvalidHeaderName { source: InvalidHeaderName },
83    InvalidHeaderValue { source: InvalidHeaderValue },
84    InvalidUri { source: InvalidUri },
85    UnsupportedIdentityType,
86}
87
88#[derive(Debug)]
89pub(crate) struct CanonicalRequestError {
90    kind: CanonicalRequestErrorKind,
91}
92
93impl fmt::Display for CanonicalRequestError {
94    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        use CanonicalRequestErrorKind::*;
96        match self.kind {
97            InvalidHeaderName { .. } => write!(f, "invalid header name"),
98            InvalidHeaderValue { .. } => write!(f, "invalid header value"),
99            InvalidUri { .. } => write!(f, "the uri was invalid"),
100            UnsupportedIdentityType => {
101                write!(f, "only AWS credentials are supported for signing")
102            }
103        }
104    }
105}
106
107impl Error for CanonicalRequestError {
108    fn source(&self) -> Option<&(dyn Error + 'static)> {
109        use CanonicalRequestErrorKind::*;
110        match &self.kind {
111            InvalidHeaderName { source } => Some(source),
112            InvalidHeaderValue { source } => Some(source),
113            InvalidUri { source } => Some(source),
114            UnsupportedIdentityType => None,
115        }
116    }
117}
118
119impl CanonicalRequestError {
120    pub(crate) fn unsupported_identity_type() -> Self {
121        Self {
122            kind: CanonicalRequestErrorKind::UnsupportedIdentityType,
123        }
124    }
125}
126
127impl From<InvalidHeaderName> for CanonicalRequestError {
128    fn from(source: InvalidHeaderName) -> Self {
129        Self {
130            kind: CanonicalRequestErrorKind::InvalidHeaderName { source },
131        }
132    }
133}
134
135impl From<InvalidHeaderValue> for CanonicalRequestError {
136    fn from(source: InvalidHeaderValue) -> Self {
137        Self {
138            kind: CanonicalRequestErrorKind::InvalidHeaderValue { source },
139        }
140    }
141}
142
143impl From<InvalidUri> for CanonicalRequestError {
144    fn from(source: InvalidUri) -> Self {
145        Self {
146            kind: CanonicalRequestErrorKind::InvalidUri { source },
147        }
148    }
149}