daaki_message/error.rs
1//! Typed error enum for email message parsing and building.
2//!
3//! # References
4//! - RFC 5322 (Internet Message Format)
5//! - RFC 2045–2047 (MIME)
6
7/// Errors that can occur during email message parsing or building.
8#[non_exhaustive]
9#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum Error {
12 /// Empty input provided to the parser (RFC 5322 Section 3.5 — a valid
13 /// message must contain at least header fields, so zero bytes is invalid).
14 #[error("empty input: no message bytes provided")]
15 EmptyInput,
16
17 /// Missing required `From` header (RFC 5322 Section 3.6.2).
18 #[error("missing required From header (RFC 5322 Section 3.6.2)")]
19 MissingFrom,
20
21 /// Date header could not be parsed per RFC 5322 Section 3.3.
22 #[error("invalid date: {0}")]
23 InvalidDate(String),
24
25 /// Syntactically invalid email address (RFC 5322 Section 3.4).
26 #[error("invalid email address: {0}")]
27 InvalidAddress(String),
28
29 /// Missing `Sender` header when `From` has multiple addresses
30 /// (RFC 5322 Section 3.6.2).
31 ///
32 /// RFC 5322: "If the from field contains more than one mailbox
33 /// specification in the mailbox-list, then the sender field, containing
34 /// the field value corresponding to the responsible agent of the message
35 /// MUST be present in the message."
36 #[error(
37 "Sender header required when From has multiple addresses \
38 (RFC 5322 Section 3.6.2)"
39 )]
40 MissingSender,
41
42 /// Invalid header field name (RFC 5322 Section 2.2).
43 ///
44 /// The name is empty, contains non-ftext characters, or is otherwise
45 /// malformed per RFC 5322 Section 2.2 (`field-name = 1*ftext`).
46 #[error("invalid header name: {0}")]
47 InvalidHeaderName(String),
48
49 /// Invalid message-ID (RFC 5322 Section 3.6.4).
50 ///
51 /// The value is empty, missing the `@` separator, contains prohibited
52 /// characters, or has empty `id-left` / `id-right` parts.
53 #[error("invalid message-ID: {0}")]
54 InvalidMessageId(String),
55
56 /// A header value contains a token or whitespace run that cannot be folded
57 /// within the 998-octet line limit (RFC 5322 Sections 2.1.1, 2.2.3).
58 #[error("header line too long: {0}")]
59 HeaderLineTooLong(String),
60
61 /// An `extra_headers` entry uses a field name reserved for standard headers
62 /// managed by the builder (RFC 5322 Section 3.6).
63 #[error("reserved header name: {0}")]
64 ReservedHeaderName(String),
65
66 /// An attachment violates MIME constraints — invalid content encoding,
67 /// missing required headers, or prohibited bytes (RFC 2045/2046).
68 #[error("invalid attachment: {0}")]
69 InvalidAttachment(String),
70
71 /// A trace header (Return-Path / Received) violates
72 /// RFC 5322 Section 3.6.7 syntax or cardinality rules.
73 #[error("invalid trace header: {0}")]
74 InvalidTraceHeader(String),
75
76 /// A Resent-* header violates RFC 5322 Section 3.6.6 syntax,
77 /// cardinality, or block-grouping rules.
78 #[error("invalid resent header: {0}")]
79 InvalidResentHeader(String),
80}
81
82#[cfg(test)]
83#[path = "error_tests.rs"]
84mod tests;