1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

//! This module contains all errors that can happen in the (`parent`)[`super`] module

pub use crate::exec::ExecError;

use super::{
	email::{EmailError, ImapError},
	http::HttpError,
	reddit::RedditError,
	twitter::TwitterError,
};

use roux::util::RouxError;
use std::{error::Error as StdError, path::PathBuf};

#[allow(missing_docs)] // error message is self-documenting
#[derive(thiserror::Error, Debug)]
pub enum SourceError {
	#[error("Can't create a source with an empty source list")]
	EmptySourceList,

	#[error("Can't create a source with a source list that contains different source variants")]
	SourceListHasDifferentVariants,

	#[error("Can't read file {}", .1.to_string_lossy())]
	FileRead(#[source] std::io::Error, PathBuf),

	#[error("HTTP error")]
	Http(#[from] HttpError),

	#[error("Email error")]
	Email(#[from] Box<EmailError>),

	#[error("Twitter error")]
	Twitter(#[from] TwitterError),

	#[error("Reddit error")]
	Reddit(#[from] RedditError),

	#[error("Exec error")]
	Exec(#[from] ExecError),
}

impl From<EmailError> for SourceError {
	fn from(e: EmailError) -> Self {
		SourceError::Email(Box::new(e))
	}
}

impl SourceError {
	pub(crate) fn is_connection_err(&self) -> Option<&(dyn StdError + Send + Sync)> {
		#[allow(clippy::match_same_arms)]
		match self {
			Self::Http(_) => Some(self),
			Self::Email(email_err) => match &**email_err {
				EmailError::Imap(ImapError::TlsInitFailed(_)) => Some(self),
				_ => None,
			},
			Self::Twitter(
				TwitterError::Auth(egg_mode::error::Error::NetError(_))
				| TwitterError::Other(egg_mode::error::Error::NetError(_)),
			) => Some(self),
			Self::Reddit(RedditError::Reddit(RouxError::Network(_))) => Some(self),
			_ => None,
		}
	}
}