aws_sdk_s3/
s3_request_id.rs

1// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
2/*
3 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7use aws_smithy_runtime_api::client::result::SdkError;
8use aws_smithy_runtime_api::http::{Headers, Response};
9use aws_smithy_types::error::metadata::{Builder as ErrorMetadataBuilder, ErrorMetadata};
10
11const EXTENDED_REQUEST_ID: &str = "s3_extended_request_id";
12
13/// Trait to retrieve the S3-specific extended request ID
14///
15/// Read more at <https://aws.amazon.com/premiumsupport/knowledge-center/s3-request-id-values/>.
16pub trait RequestIdExt {
17    /// Returns the S3 Extended Request ID necessary when contacting AWS Support.
18    fn extended_request_id(&self) -> Option<&str>;
19}
20
21impl<E> RequestIdExt for SdkError<E, Response> {
22    fn extended_request_id(&self) -> Option<&str> {
23        match self {
24            Self::ResponseError(err) => err.raw().headers().extended_request_id(),
25            Self::ServiceError(err) => err.raw().headers().extended_request_id(),
26            _ => None,
27        }
28    }
29}
30
31impl RequestIdExt for ErrorMetadata {
32    fn extended_request_id(&self) -> Option<&str> {
33        self.extra(EXTENDED_REQUEST_ID)
34    }
35}
36
37impl<B> RequestIdExt for Response<B> {
38    fn extended_request_id(&self) -> Option<&str> {
39        self.headers().extended_request_id()
40    }
41}
42
43impl RequestIdExt for Headers {
44    fn extended_request_id(&self) -> Option<&str> {
45        self.get("x-amz-id-2")
46    }
47}
48
49impl<O, E> RequestIdExt for Result<O, E>
50where
51    O: RequestIdExt,
52    E: RequestIdExt,
53{
54    fn extended_request_id(&self) -> Option<&str> {
55        match self {
56            Ok(ok) => ok.extended_request_id(),
57            Err(err) => err.extended_request_id(),
58        }
59    }
60}
61
62/// Applies the extended request ID to a generic error builder
63pub(crate) fn apply_extended_request_id(builder: ErrorMetadataBuilder, headers: &Headers) -> ErrorMetadataBuilder {
64    if let Some(extended_request_id) = headers.extended_request_id() {
65        builder.custom(EXTENDED_REQUEST_ID, extended_request_id)
66    } else {
67        builder
68    }
69}
70
71#[cfg(test)]
72mod test {
73    use super::*;
74    use aws_smithy_runtime_api::client::result::SdkError;
75    use aws_smithy_types::body::SdkBody;
76
77    #[test]
78    fn handle_missing_header() {
79        let resp = Response::try_from(http::Response::builder().status(400).body("").unwrap()).unwrap();
80        let mut builder = ErrorMetadata::builder().message("123");
81        builder = apply_extended_request_id(builder, resp.headers());
82        assert_eq!(builder.build().extended_request_id(), None);
83    }
84
85    #[test]
86    fn test_extended_request_id_sdk_error() {
87        let without_extended_request_id = || Response::try_from(http::Response::builder().body(SdkBody::empty()).unwrap()).unwrap();
88        let with_extended_request_id = || {
89            Response::try_from(
90                http::Response::builder()
91                    .header("x-amz-id-2", "some-request-id")
92                    .body(SdkBody::empty())
93                    .unwrap(),
94            )
95            .unwrap()
96        };
97        assert_eq!(
98            None,
99            SdkError::<(), _>::response_error("test", without_extended_request_id()).extended_request_id()
100        );
101        assert_eq!(
102            Some("some-request-id"),
103            SdkError::<(), _>::response_error("test", with_extended_request_id()).extended_request_id()
104        );
105        assert_eq!(None, SdkError::service_error((), without_extended_request_id()).extended_request_id());
106        assert_eq!(
107            Some("some-request-id"),
108            SdkError::service_error((), with_extended_request_id()).extended_request_id()
109        );
110    }
111
112    #[test]
113    fn test_extract_extended_request_id() {
114        let mut headers = Headers::new();
115        assert_eq!(None, headers.extended_request_id());
116
117        headers.append("x-amz-id-2", "some-request-id");
118        assert_eq!(Some("some-request-id"), headers.extended_request_id());
119    }
120
121    #[test]
122    fn test_apply_extended_request_id() {
123        let mut headers = Headers::new();
124        assert_eq!(
125            ErrorMetadata::builder().build(),
126            apply_extended_request_id(ErrorMetadata::builder(), &headers).build(),
127        );
128
129        headers.append("x-amz-id-2", "some-request-id");
130        assert_eq!(
131            ErrorMetadata::builder().custom(EXTENDED_REQUEST_ID, "some-request-id").build(),
132            apply_extended_request_id(ErrorMetadata::builder(), &headers).build(),
133        );
134    }
135
136    #[test]
137    fn test_error_metadata_extended_request_id_impl() {
138        let err = ErrorMetadata::builder().custom(EXTENDED_REQUEST_ID, "some-request-id").build();
139        assert_eq!(Some("some-request-id"), err.extended_request_id());
140    }
141}