aws_smithy_runtime_api/client/interceptors/
error.rs
1use crate::box_error::BoxError;
9use std::fmt;
10
11macro_rules! interceptor_error_fn {
12 ($fn_name:ident => $error_kind:ident (with source)) => {
13 #[doc = concat!("Create a new error indicating a failure with a ", stringify!($fn_name), " interceptor.")]
14 pub fn $fn_name(
15 interceptor_name: impl Into<String>,
16 source: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
17 ) -> Self {
18 Self {
19 kind: ErrorKind::$error_kind,
20 interceptor_name: Some(interceptor_name.into()),
21 source: Some(source.into()),
22 }
23 }
24 };
25 ($fn_name:ident => $error_kind:ident (invalid $thing:ident access)) => {
26 #[doc = concat!("Create a new error indicating that an interceptor tried to access the ", stringify!($thing), " out of turn.")]
27 pub fn $fn_name() -> Self {
28 Self {
29 kind: ErrorKind::$error_kind,
30 interceptor_name: None,
31 source: None,
32 }
33 }
34 }
35}
36
37#[derive(Debug)]
39pub struct InterceptorError {
40 kind: ErrorKind,
41 interceptor_name: Option<String>,
42 source: Option<BoxError>,
43}
44
45impl InterceptorError {
46 interceptor_error_fn!(read_before_execution => ReadBeforeExecution (with source));
47 interceptor_error_fn!(modify_before_serialization => ModifyBeforeSerialization (with source));
48 interceptor_error_fn!(read_before_serialization => ReadBeforeSerialization (with source));
49 interceptor_error_fn!(read_after_serialization => ReadAfterSerialization (with source));
50 interceptor_error_fn!(modify_before_retry_loop => ModifyBeforeRetryLoop (with source));
51 interceptor_error_fn!(read_before_attempt => ReadBeforeAttempt (with source));
52 interceptor_error_fn!(modify_before_signing => ModifyBeforeSigning (with source));
53 interceptor_error_fn!(read_before_signing => ReadBeforeSigning (with source));
54 interceptor_error_fn!(read_after_signing => ReadAfterSigning (with source));
55 interceptor_error_fn!(modify_before_transmit => ModifyBeforeTransmit (with source));
56 interceptor_error_fn!(read_before_transmit => ReadBeforeTransmit (with source));
57 interceptor_error_fn!(read_after_transmit => ReadAfterTransmit (with source));
58 interceptor_error_fn!(modify_before_deserialization => ModifyBeforeDeserialization (with source));
59 interceptor_error_fn!(read_before_deserialization => ReadBeforeDeserialization (with source));
60 interceptor_error_fn!(read_after_deserialization => ReadAfterDeserialization (with source));
61 interceptor_error_fn!(modify_before_attempt_completion => ModifyBeforeAttemptCompletion (with source));
62 interceptor_error_fn!(read_after_attempt => ReadAfterAttempt (with source));
63 interceptor_error_fn!(modify_before_completion => ModifyBeforeCompletion (with source));
64 interceptor_error_fn!(read_after_execution => ReadAfterExecution (with source));
65
66 interceptor_error_fn!(modify_before_attempt_completion_failed => ModifyBeforeAttemptCompletion (with source));
67 interceptor_error_fn!(read_after_attempt_failed => ReadAfterAttempt (with source));
68 interceptor_error_fn!(modify_before_completion_failed => ModifyBeforeCompletion (with source));
69 interceptor_error_fn!(read_after_execution_failed => ReadAfterExecution (with source));
70
71 interceptor_error_fn!(invalid_request_access => InvalidRequestAccess (invalid request access));
72 interceptor_error_fn!(invalid_response_access => InvalidResponseAccess (invalid response access));
73 interceptor_error_fn!(invalid_input_access => InvalidInputAccess (invalid input access));
74 interceptor_error_fn!(invalid_output_access => InvalidOutputAccess (invalid output access));
75}
76
77#[derive(Debug)]
78enum ErrorKind {
79 ReadBeforeExecution,
81 ModifyBeforeSerialization,
83 ReadBeforeSerialization,
85 ReadAfterSerialization,
87 ModifyBeforeRetryLoop,
89 ReadBeforeAttempt,
91 ModifyBeforeSigning,
93 ReadBeforeSigning,
95 ReadAfterSigning,
97 ModifyBeforeTransmit,
99 ReadBeforeTransmit,
101 ReadAfterTransmit,
103 ModifyBeforeDeserialization,
105 ReadBeforeDeserialization,
107 ReadAfterDeserialization,
109 ModifyBeforeAttemptCompletion,
111 ReadAfterAttempt,
113 ModifyBeforeCompletion,
115 ReadAfterExecution,
117 InvalidRequestAccess,
119 InvalidResponseAccess,
121 InvalidInputAccess,
123 InvalidOutputAccess,
125}
126
127macro_rules! display_interceptor_err {
128 ($self:ident, $f:ident, $(($error_kind:ident => $fn_name:ident ($($option:tt)+)),)+) => {
129 {
130 use ErrorKind::*;
131 match &$self.kind {
132 $($error_kind => display_interceptor_err!($self, $f, $fn_name, ($($option)+)),)+
133 }
134 }
135 };
136 ($self:ident, $f:ident, $fn_name:ident, (interceptor error)) => {{
137 $f.write_str($self.interceptor_name.as_deref().unwrap_or_default())?;
138 $f.write_str(concat!(" ", stringify!($fn_name), " interceptor encountered an error"))
139 }};
140 ($self:ident, $f:ident, $fn_name:ident, (invalid access $name:ident $message:literal)) => {
141 $f.write_str(concat!("tried to access the ", stringify!($name), " ", $message))
142 };
143}
144
145impl fmt::Display for InterceptorError {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 display_interceptor_err!(self, f,
148 (ReadBeforeExecution => read_before_execution (interceptor error)),
149 (ModifyBeforeSerialization => modify_before_serialization (interceptor error)),
150 (ReadBeforeSerialization => read_before_serialization (interceptor error)),
151 (ReadAfterSerialization => read_after_serialization (interceptor error)),
152 (ModifyBeforeRetryLoop => modify_before_retry_loop (interceptor error)),
153 (ReadBeforeAttempt => read_Before_attempt (interceptor error)),
154 (ModifyBeforeSigning => modify_before_signing (interceptor error)),
155 (ReadBeforeSigning => read_before_signing (interceptor error)),
156 (ReadAfterSigning => read_after_signing (interceptor error)),
157 (ModifyBeforeTransmit => modify_before_transmit (interceptor error)),
158 (ReadBeforeTransmit => read_before_transmit (interceptor error)),
159 (ReadAfterTransmit => read_after_transmit (interceptor error)),
160 (ModifyBeforeDeserialization => modify_before_deserialization (interceptor error)),
161 (ReadBeforeDeserialization => read_before_deserialization (interceptor error)),
162 (ReadAfterDeserialization => read_after_deserialization (interceptor error)),
163 (ModifyBeforeAttemptCompletion => modify_before_attempt_completion (interceptor error)),
164 (ReadAfterAttempt => read_after_attempt (interceptor error)),
165 (ModifyBeforeCompletion => modify_before_completion (interceptor error)),
166 (ReadAfterExecution => read_after_execution (interceptor error)),
167 (InvalidRequestAccess => invalid_request_access (invalid access request "before request serialization")),
168 (InvalidResponseAccess => invalid_response_access (invalid access response "before transmitting a request")),
169 (InvalidInputAccess => invalid_input_access (invalid access input "after request serialization")),
170 (InvalidOutputAccess => invalid_output_access (invalid access output "before response deserialization")),
171 )
172 }
173}
174
175impl std::error::Error for InterceptorError {
176 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
177 self.source.as_ref().map(|err| err.as_ref() as _)
178 }
179}
180
181#[derive(Debug)]
183pub struct ContextAttachedError {
184 context: String,
185 source: Option<BoxError>,
186}
187
188impl ContextAttachedError {
189 pub fn new(context: impl Into<String>, source: impl Into<BoxError>) -> Self {
191 Self {
192 context: context.into(),
193 source: Some(source.into()),
194 }
195 }
196}
197
198impl fmt::Display for ContextAttachedError {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 write!(f, "{}", self.context)
201 }
202}
203
204impl std::error::Error for ContextAttachedError {
205 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
206 self.source.as_ref().map(|err| err.as_ref() as _)
207 }
208}