twilight_interactions/
error.rs

1//! Error types used by the crate.
2
3use std::{
4    error::Error,
5    fmt::{Display, Formatter, Result as FmtResult},
6};
7
8use twilight_model::{application::command::CommandOptionType, channel::ChannelType};
9
10/// Error when parsing a command.
11///
12/// This error type is returned by the [`CommandModel::from_interaction`]
13/// method.
14///
15/// [`CommandModel::from_interaction`]: crate::command::CommandModel::from_interaction
16#[derive(Debug, Clone, PartialEq)]
17pub enum ParseError {
18    /// Received empty option list.
19    ///
20    /// This error is only returned when parsing subcommands.
21    EmptyOptions,
22    /// Error when parsing a command option.
23    Option(ParseOptionError),
24}
25
26impl Error for ParseError {}
27
28impl Display for ParseError {
29    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
30        match self {
31            ParseError::EmptyOptions => write!(f, "received an empty option list"),
32            ParseError::Option(error) => error.fmt(f),
33        }
34    }
35}
36
37/// Error when parsing a command option.
38///
39/// This type is used by [`ParseError`].
40#[derive(Debug, Clone, PartialEq)]
41pub struct ParseOptionError {
42    /// The name of the option field that caused the error.
43    pub field: String,
44    /// The type of the error.
45    pub kind: ParseOptionErrorType,
46}
47
48impl Error for ParseOptionError {}
49
50impl Display for ParseOptionError {
51    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
52        write!(f, "failed to parse option `{}`: ", self.field)?;
53
54        match &self.kind {
55            ParseOptionErrorType::InvalidType(ty) => write!(f, "invalid type, found {}", ty.kind()),
56            ParseOptionErrorType::InvalidChoice(choice) => {
57                write!(f, "invalid choice value, found `{choice}`")
58            }
59            ParseOptionErrorType::IntegerOutOfRange(val) => {
60                write!(f, "out of range integer, received `{val}`")
61            }
62            ParseOptionErrorType::NumberOutOfRange(val) => {
63                write!(f, "out of range number, received `{val}`")
64            }
65            ParseOptionErrorType::StringLengthOutOfRange(val) => {
66                write!(f, "out of range string length, received `{val}`")
67            }
68            ParseOptionErrorType::InvalidChannelType(kind) => {
69                write!(f, "invalid channel type, received `{}`", kind.name())
70            }
71            ParseOptionErrorType::LookupFailed(id) => write!(f, "failed to resolve `{id}`"),
72            ParseOptionErrorType::UnknownField => write!(f, "unknown field"),
73            ParseOptionErrorType::UnknownSubcommand => write!(f, "unknown subcommand"),
74            ParseOptionErrorType::RequiredField => write!(f, "missing required field"),
75        }
76    }
77}
78
79/// Type of [`ParseOptionError`] that occurred.
80#[derive(Debug, Clone, PartialEq)]
81pub enum ParseOptionErrorType {
82    /// Received an invalid option type.
83    InvalidType(CommandOptionType),
84    /// Received an invalid value on choice option type.
85    InvalidChoice(String),
86    /// Received an out of range integer.
87    IntegerOutOfRange(i64),
88    /// Received an out of range floating point number.
89    NumberOutOfRange(f64),
90    /// Received an out of range string.
91    StringLengthOutOfRange(String),
92    /// Received an invalid channel type.
93    InvalidChannelType(ChannelType),
94    /// Failed to resolve data associated with an ID.
95    LookupFailed(u64),
96    /// Missing a required option field.
97    RequiredField,
98    /// Received an unknown option field.
99    UnknownField,
100    /// Received an unknown subcommand.
101    UnknownSubcommand,
102}