aws_smithy_eventstream/
error.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use aws_smithy_types::DateTime;
7use std::error::Error as StdError;
8use std::fmt;
9
10#[derive(Debug)]
11pub(crate) enum ErrorKind {
12    HeadersTooLong,
13    HeaderValueTooLong,
14    InvalidHeaderNameLength,
15    InvalidHeaderValue,
16    InvalidHeaderValueType(u8),
17    InvalidHeadersLength,
18    InvalidMessageLength,
19    InvalidUtf8String,
20    MessageChecksumMismatch(u32, u32),
21    MessageTooLong,
22    PayloadTooLong,
23    PreludeChecksumMismatch(u32, u32),
24    TimestampValueTooLarge(DateTime),
25    Marshalling(String),
26    Unmarshalling(String),
27}
28
29#[derive(Debug)]
30pub struct Error {
31    kind: ErrorKind,
32}
33
34impl Error {
35    // Used in tests to match on the underlying error kind
36    #[cfg(test)]
37    pub(crate) fn kind(&self) -> &ErrorKind {
38        &self.kind
39    }
40
41    /// Create an `Error` for failure to marshall a message from a Smithy shape
42    pub fn marshalling(message: impl Into<String>) -> Self {
43        Self {
44            kind: ErrorKind::Marshalling(message.into()),
45        }
46    }
47
48    /// Create an `Error` for failure to unmarshall a message into a Smithy shape
49    pub fn unmarshalling(message: impl Into<String>) -> Self {
50        Self {
51            kind: ErrorKind::Unmarshalling(message.into()),
52        }
53    }
54
55    /// Returns true if the error is one generated during serialization
56    pub fn is_invalid_message(&self) -> bool {
57        use ErrorKind::*;
58        matches!(
59            self.kind,
60            HeadersTooLong
61                | PayloadTooLong
62                | MessageTooLong
63                | InvalidHeaderNameLength
64                | TimestampValueTooLarge(_)
65                | Marshalling(_)
66        )
67    }
68}
69
70impl From<ErrorKind> for Error {
71    fn from(kind: ErrorKind) -> Self {
72        Error { kind }
73    }
74}
75
76impl StdError for Error {}
77
78impl fmt::Display for Error {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        use ErrorKind::*;
81        match &self.kind {
82            HeadersTooLong => write!(f, "headers too long to fit in event stream frame"),
83            HeaderValueTooLong => write!(f, "header value too long to fit in event stream frame"),
84            InvalidHeaderNameLength => write!(f, "invalid header name length"),
85            InvalidHeaderValue => write!(f, "invalid header value"),
86            InvalidHeaderValueType(val) => write!(f, "invalid header value type: {}", val),
87            InvalidHeadersLength => write!(f, "invalid headers length"),
88            InvalidMessageLength => write!(f, "invalid message length"),
89            InvalidUtf8String => write!(f, "encountered invalid UTF-8 string"),
90            MessageChecksumMismatch(expected, actual) => write!(
91                f,
92                "message checksum 0x{:X} didn't match expected checksum 0x{:X}",
93                actual, expected
94            ),
95            MessageTooLong => write!(f, "message too long to fit in event stream frame"),
96            PayloadTooLong => write!(f, "message payload too long to fit in event stream frame"),
97            PreludeChecksumMismatch(expected, actual) => write!(
98                f,
99                "prelude checksum 0x{:X} didn't match expected checksum 0x{:X}",
100                actual, expected
101            ),
102            TimestampValueTooLarge(time) => write!(
103                f,
104                "timestamp value {:?} is too large to fit into an i64",
105                time
106            ),
107            Marshalling(error) => write!(f, "failed to marshall message: {}", error),
108            Unmarshalling(error) => write!(f, "failed to unmarshall message: {}", error),
109        }
110    }
111}