Unverified Commit 47702e45 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Gracefully handle alternate error message fields (#374)

Errors returned by AWS services may be stored at `Message`, `message` or `errorMessage`. This updates the relevant code to search all three locations when surfacing a clean error message to the customer. This diff also fixes a long-standing shortcoming of SdkError where it failed to provide a clean Display implementation.
parent 06547435
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -71,8 +71,9 @@ class ErrorGenerator(

    private fun renderError() {
        val symbol = symbolProvider.toSymbol(shape)
        val messageShape = shape.getMember("message")
        val message = messageShape.map { "self.message.as_deref()" }.orElse("None")
        val messageShape =
            shape.getMember("message").or { shape.getMember("Message") }.or { shape.getMember("errorMessage") }
        val message = messageShape.map { "self.${symbolProvider.toMemberName(it)}.as_deref()" }.orElse("None")
        val errorKindT = RuntimeType.errorKind(symbolProvider.config().runtimeConfig)
        writer.rustBlock("impl ${symbol.name}") {
            val retryKindWriteable = shape.modeledRetryKind(error)?.writable(symbolProvider.config().runtimeConfig)
+24 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ pub fn parse_generic_error<B>(
        .map(|s| sanitize_error_code(s).to_string());
    let message = body
        .get("message")
        .or_else(|| body.get("Message"))
        .or_else(|| body.get("errorMessage"))
        .and_then(|v| v.as_str())
        .map(|s| s.to_string());
    let request_id = response
@@ -134,4 +136,26 @@ mod test {
            "FooError"
        );
    }

    // services like lambda use an alternate `Message` instead of `message`
    #[test]
    fn alternative_error_message_names() {
        let response = http::Response::builder()
            .header("x-amzn-errortype", "ResourceNotFoundException")
            .body(json!({
                "Type": "User",
                "Message": "Functions from 'us-west-2' are not reachable from us-east-1"
            }))
            .unwrap();
        assert_eq!(
            parse_generic_error(&response, response.body()),
            Error {
                code: Some("ResourceNotFoundException".to_string()),
                message: Some(
                    "Functions from 'us-west-2' are not reachable from us-east-1".to_string()
                ),
                request_id: None,
            }
        )
    }
}
+6 −1
Original line number Diff line number Diff line
@@ -45,7 +45,12 @@ where
    E: Error,
{
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
        match self {
            SdkError::ConstructionFailure(err) => Display::fmt(&err, f),
            SdkError::DispatchFailure(err) => Display::fmt(&err, f),
            SdkError::ResponseError { err, .. } => Display::fmt(&err, f),
            SdkError::ServiceError { err, .. } => Display::fmt(&err, f),
        }
    }
}