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
111
112
113
use super::ModuleFeatureInfo;
use super::ModuleInfo;
use super::ServerId;
use irc;
use rand;
use serde_yaml;
use std::any::Any;
use std::borrow::Cow;
use std::io;
use util;

error_chain! {
    foreign_links {
        Io(io::Error);

        Rand(rand::Error);

        SerdeYaml(serde_yaml::Error);
    }

    links {
        YamlUtil(util::yaml::Error, util::yaml::ErrorKind);
    }

    errors {
        // TODO: Once I switch from `error-chain` to `failure`, integrate with `irc`'s `failure`
        // support.
        IrcCrate(inner: irc::error::IrcError) {
            description("IRC error")
            display("IRC error: {}", inner)
        }

        ModuleRegistryClash(old: ModuleInfo, new: ModuleInfo) {
            description("module registry clash")
            display("Failed to load a new module because it would have overwritten an old module. \
                     Old: {:?}; new: {:?}.",
                    old,
                    new)
        }

        ModuleFeatureRegistryClash(old: ModuleFeatureInfo, new: ModuleFeatureInfo) {
            description("module feature registry clash")
            display("Failed to load a new module feature because it would have overwritten an old \
                     module feature. Old: {:?}; new: {:?}.",
                    old,
                    new)
        }

        ServerRegistryClash(server_id: ServerId) {
            description("server registry UUID clash")
            display("Failed to register a server because an existing server had the same UUID: \
                     {uuid}",
                    uuid = server_id.uuid.hyphenated())
        }

        Config(key: String, problem: String) {
            description("configuration error")
            display("Configuration error: Key {:?} {}.", key, problem)
        }

        ThreadSpawnFailure(io_err: io::Error) {
            description("failed to spawn thread")
            display("Failed to spawn thread: {}", io_err)
        }

        HandlerPanic(
            feature_kind: Cow<'static, str>,
            feature_name: Cow<'static, str>,
            payload: Box<Any + Send + 'static>
        ) {
            description("panic in module feature handler function")
            display("The handler function for {} {:?} panicked with the following message: {}",
                    feature_kind,
                    feature_name,
                    util::fmt::FmtAny(payload.as_ref()))
        }

        NicknameUnknown {
            description("nickname retrieval error")
            display("Puzzlingly, the bot seems to have forgotten its own nickname.")
        }

        UnknownServer(server_id: ServerId) {
            description("server ID not recognized")
            display("An attempt to look up a server connection or metadatum thereof failed, \
                     because the given server identification token (UUID {id}) was not a valid \
                     key in the relevant associative array.",
                    id = server_id.uuid.hyphenated())
        }

        LockPoisoned(lock_contents_desc: Cow<'static, str>) {
            description("lock poisoned")
            display("A thread panicked, poisoning a lock around {}.", lock_contents_desc)
        }

        Any(inner: Box<Any + Send + 'static>) {
            description("miscellaneous error")
            display("Error: {}", util::fmt::FmtAny(inner.as_ref()))
        }

        Unit {
            description("unknown error")
            display("An error seems to have occurred, but unfortunately the error type provided \
                     was the unit type, containing no information about the error.")
        }
    }
}

impl From<irc::error::IrcError> for Error {
    fn from(orig: irc::error::IrcError) -> Self {
        ErrorKind::IrcCrate(orig).into()
    }
}