Skip to main content

autumn_plugin_slack/
error.rs

1//! Error types.
2
3use crate::verify::VerifyError;
4
5/// Error from a handler. Any error type converts with `?`.
6pub type HandlerError = Box<dyn std::error::Error + Send + Sync + 'static>;
7
8/// Result of a handler.
9pub type HandlerResult<T> = Result<T, HandlerError>;
10
11/// Plugin and client errors. Messages never hold a token or a secret.
12#[derive(Debug, thiserror::Error)]
13#[non_exhaustive]
14pub enum SlackError {
15    /// Bad config or bad input from the app.
16    #[error("slack config: {0}")]
17    Config(String),
18    /// Slack replied `ok: false`.
19    #[error("slack {method} failed: {code}")]
20    Api {
21        /// Web API method.
22        method: String,
23        /// Slack error code, for example `channel_not_found`.
24        code: String,
25        /// Scope that the call needs, if Slack names one.
26        needed: Option<String>,
27    },
28    /// Slack replied 429 and the client stopped.
29    #[error("slack rate limited (retry after {retry_after_secs:?} s)")]
30    RateLimited {
31        /// The `Retry-After` value, if any.
32        retry_after_secs: Option<u64>,
33    },
34    /// Slack replied with an HTTP error status.
35    #[error("slack http {status}")]
36    Http {
37        /// HTTP status.
38        status: u16,
39        /// First bytes of the body.
40        body: String,
41    },
42    /// No HTTP reply: connect error or timeout.
43    #[error("slack transport: {0}")]
44    Transport(String),
45    /// The reply is not the expected JSON.
46    #[error("slack reply decode: {0}")]
47    Decode(String),
48    /// The `response_url` is not an allowed Slack URL.
49    #[error("response_url is not an allowed Slack URL")]
50    BadResponseUrl,
51    /// Request verification failed.
52    #[error(transparent)]
53    Verify(#[from] VerifyError),
54}
55
56impl SlackError {
57    /// Returns the Slack error code for an [`SlackError::Api`] error.
58    #[must_use]
59    pub fn slack_code(&self) -> Option<&str> {
60        match self {
61            Self::Api { code, .. } => Some(code),
62            _ => None,
63        }
64    }
65}