aws_smithy_http_server/
runtime_error.rs1use crate::{extension::RuntimeErrorExtension, response::IntoResponse};
7
8pub struct InternalFailureException;
18
19pub const INVALID_HTTP_RESPONSE_FOR_RUNTIME_ERROR_PANIC_MESSAGE: &str = "invalid HTTP response for `RuntimeError`; please file a bug report under https://github.com/smithy-lang/smithy-rs/issues";
20
21#[non_exhaustive]
32#[derive(Debug, thiserror::Error)]
33pub enum RuntimeError {
34 #[error("request failed to deserialize or response failed to serialize: {0}")]
36 Serialization(crate::error::Error),
37 #[error("internal failure: {0}")]
39 InternalFailure(crate::error::Error),
40 #[error("not acceptable request: request contains an `Accept` header with a MIME type, and the server cannot return a response body adhering to that MIME type")]
42 NotAcceptable,
43 #[error("unsupported media type: request does not contain the expected `Content-Type` header value")]
45 UnsupportedMediaType,
46 #[error("validation failure: {0}")]
54 Validation(String),
55}
56
57impl From<InternalFailureException> for RuntimeError {
58 fn from(_: InternalFailureException) -> Self {
59 Self::InternalFailure(crate::error::Error::new(String::new()))
60 }
61}
62
63impl RuntimeError {
64 pub fn name(&self) -> &'static str {
66 match self {
67 Self::Serialization(_) => "SerializationException",
68 Self::InternalFailure(_) => "InternalFailureException",
69 Self::NotAcceptable => "NotAcceptableException",
70 Self::UnsupportedMediaType => "UnsupportedMediaTypeException",
71 Self::Validation(_) => "ValidationException",
72 }
73 }
74
75 pub fn status_code(&self) -> http::StatusCode {
77 match self {
78 Self::Serialization(_) | Self::Validation(_) => http::StatusCode::BAD_REQUEST,
79 Self::InternalFailure(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
80 Self::NotAcceptable => http::StatusCode::NOT_ACCEPTABLE,
81 Self::UnsupportedMediaType => http::StatusCode::UNSUPPORTED_MEDIA_TYPE,
82 }
83 }
84}
85
86impl<P> IntoResponse<P> for RuntimeError {
87 fn into_response(self) -> crate::response::Response {
88 let mut response = http::Response::new(crate::body::empty());
89 *response.status_mut() = self.status_code();
90 response
91 .extensions_mut()
92 .insert(RuntimeErrorExtension::new(self.name().to_owned()));
93 response
94 }
95
96 fn into_response_with_protocol(self, protocol: &dyn crate::schema::ServerProtocol) -> crate::response::Response {
97 protocol.serialize_runtime_error(self)
98 }
99}
100
101macro_rules! tuple_internal_failure {
102 ($($protocol:ident),+) => {
103 impl<$($protocol),+> IntoResponse<($($protocol,)+)> for InternalFailureException {
104 fn into_response(self) -> crate::response::Response {
105 IntoResponse::<()>::into_response(RuntimeError::from(self))
106 }
107
108 fn into_response_with_protocol(self, protocol: &dyn crate::schema::ServerProtocol) -> crate::response::Response {
109 protocol.serialize_runtime_error(self.into())
110 }
111
112 }
113 };
114}
115
116tuple_internal_failure!(P1, P2);
117tuple_internal_failure!(P1, P2, P3);
118tuple_internal_failure!(P1, P2, P3, P4);
119tuple_internal_failure!(P1, P2, P3, P4, P5);
120tuple_internal_failure!(P1, P2, P3, P4, P5, P6);
121tuple_internal_failure!(P1, P2, P3, P4, P5, P6, P7);
122tuple_internal_failure!(P1, P2, P3, P4, P5, P6, P7, P8);
123tuple_internal_failure!(P1, P2, P3, P4, P5, P6, P7, P8, P9);
124tuple_internal_failure!(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10);
125
126macro_rules! protocol_runtime_error {
129 ($error:ty) => {
130 impl From<RuntimeError> for $error {
131 fn from(error: RuntimeError) -> Self {
132 match error {
133 RuntimeError::Serialization(error) => Self::Serialization(error),
134 RuntimeError::InternalFailure(error) => Self::InternalFailure(error),
135 RuntimeError::NotAcceptable => Self::NotAcceptable,
136 RuntimeError::UnsupportedMediaType => Self::UnsupportedMediaType,
137 RuntimeError::Validation(reason) => Self::Validation(reason.into()),
138 }
139 }
140 }
141 };
142}
143protocol_runtime_error!(crate::protocol::rest_json_1::runtime_error::RuntimeError);
144protocol_runtime_error!(crate::protocol::aws_json::runtime_error::RuntimeError);
145protocol_runtime_error!(crate::protocol::rest_xml::runtime_error::RuntimeError);