1use std::fmt;
7
8use crate::{constants, types::NaiveResponse};
9
10use thiserror::Error;
11
12#[derive(Error, Debug, PartialEq)]
18pub enum ParamError<T: PartialEq + fmt::Debug> {
19 #[error("'{value:?}' is outside bounds: {bounds:?}")]
20 OutOfBounds { bounds: (T, T), value: T },
21}
22
23impl<T: PartialEq + fmt::Debug> ParamError<T> {
24 pub fn out_of_bounds(value: T, bounds: (T, T)) -> Self {
25 Self::OutOfBounds { value, bounds }
26 }
27}
28
29#[derive(Error, Debug)]
34pub enum ApiError {
35 #[error("Client Error ({status}): {text}\n This should be prevented, please raise an issue")]
36 Client { status: u16, text: String },
37
38 #[error("Internal Server Error ({status}): {text}")]
39 Server { status: u16, text: String },
40
41 #[error("Invalid API key, make sure your key is valid")]
42 ApiKey,
43
44 #[error(
46 "You have exceeded the rate limit. This could be due to multiple programs using the API. \
47 If this is not the case then sorry but the API hates you, consider raising an issue."
48 )]
49 RateLimit,
50
51 #[error("You have exhausted the daily limit of proxies.")]
52 DailyLimit,
53
54 #[error("No matching proxies, consider broadening the parameters used")]
55 NoProxy,
56
57 #[error("The API returned an unexpected message. Consider raising an issue with the library")]
58 Unknown,
59}
60
61impl From<NaiveResponse> for ApiError {
62 fn from(naive_resp: NaiveResponse) -> Self {
63 let NaiveResponse { status, text } = naive_resp;
64
65 match Self::from(text.clone()) {
68 Self::Unknown => {
69 if (400..500).contains(&status) {
70 Self::Client { status, text }
71 } else if (500..600).contains(&status) {
72 Self::Server { status, text }
73 } else {
74 unreachable!(
75 "Tried creating ApiError from valid response ({}). Please raise an issue \
76 at {}.",
77 status,
78 constants::REPO_URI
79 );
80 }
81 }
82 err => err,
83 }
84 }
85}
86
87const INVALID_API_KEY: &str =
88 "Invalid API. Get your API to make unlimited requests at http://pubproxy.com/#premium";
89const RATE_LIMIT: &str = "We have to temporarily stop you. You're requesting proxies a little too \
90 fast (2+ requests per second). Get your API to remove this limit at
91 http://pubproxy.com/#premium";
92const DAILY_LIMIT: &str = "You reached the maximum 50 requests for today. Get your API to make \
93 unlimited requests at http://pubproxy.com/#premium";
94const NO_PROXY: &str = "No proxy";
95
96impl From<String> for ApiError {
97 fn from(s: String) -> Self {
98 match s.as_str() {
99 INVALID_API_KEY => Self::ApiKey,
100 RATE_LIMIT => Self::RateLimit,
101 DAILY_LIMIT => Self::DailyLimit,
102 NO_PROXY => Self::NoProxy,
103 _ => Self::Unknown,
104 }
105 }
106}