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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::error;
use std::io;
use std::fmt;

use reqwest;
use serde_json;

use client::Status;

/// The error type used by this library.
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum AuthyError {
    /// There was an error with the request.
    BadRequest(Status), // 400

    /// Either the API key or the verification token was invalid.
    UnauthorizedKey(Status), // 401

    /// This account does not have access to the requested service.
    Forbidden(Status), // 403

    /// The authy user could not be found
    UserNotFound(Status), // 404

    /// You have reached the API usage limit.
    TooManyRequests(Status), // 429

    /// There was an internal server error.
    InternalServerError(Status), // 500

    /// The authy service was unavailable. Only returned after the configured `retry_count`.
    ServiceUnavailable, // 503

    /// There was an IO error.
    IoError(String),

    /// There was an error deserializing a json object.
    JsonParseError(String),

    /// We made a request the server didn't like.
    RequestError(String),

    /// The server gave an invalid response.
    InvalidServerResponse,

    /// Server responded with something we don't know how to make use of.
    UnknownServerResponse(String),
}

impl error::Error for AuthyError {
    fn description(&self) -> &str {
        use AuthyError::*;
        match *self {
            BadRequest(_) => "400 bad request",
            UnauthorizedKey(_) => "401 unauthorized",
            Forbidden(_) => "403 forbidden",
            UserNotFound(_) => "404 not found",
            TooManyRequests(_) => "429 too many requests",
            InternalServerError(_) => "500 internal server error",
            ServiceUnavailable => "503 service unavailable",
            IoError(_) => "IO error",
            JsonParseError(_) => "JSON parse error",
            RequestError(_) => "Request error",
            InvalidServerResponse => "Invalid server response",
            UnknownServerResponse(_) => "Unknown server response"
        }
    }
    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

impl fmt::Display for AuthyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use AuthyError::*;

        match *self {
            BadRequest(ref s) => write!(f, "Bad Request: {}", s.message),
            UnauthorizedKey(ref s) => write!(f, "Unauthorized API Key: {}", s.message),
            Forbidden(ref s) => write!(f, "Forbidden: {}", s.message),
            UserNotFound(ref s) => write!(f, "User Not Found: {}", s.message),
            TooManyRequests(ref s) => write!(f, "Too Many Requests: {}", s.message),
            InternalServerError(ref s) => write!(f, "Internal Server Error: {}", s.message),
            ServiceUnavailable => write!(f, "Service Unavailable reported by authy service"),
            IoError(ref s) => write!(f, "IO Error: {}", s),
            JsonParseError(ref s) => write!(f, "Json parsing error: {}", s),
            RequestError(ref s) => write!(f, "Request error: {}", s),
            InvalidServerResponse => write!(f, "Server returned an invalid response"),
            UnknownServerResponse(ref s) => write!(f, "Server returned a response we don't know how to process: {}", s),
        }
    }
}

impl From<reqwest::Error> for AuthyError {
    fn from(e: reqwest::Error) -> Self {
        AuthyError::RequestError(e.to_string())
    }
}

impl From<serde_json::Error> for AuthyError {
    fn from(e: serde_json::Error) -> Self {
        AuthyError::JsonParseError(e.to_string())
    }
}

impl From<io::Error> for AuthyError {
    fn from(e: io::Error) -> Self {
        AuthyError::IoError(e.to_string())
    }
}