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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Error type used for the tests.

use core::convert::{From, Into};
use eyre::Report;
use flex_error::{define_error, TraceError};
use ibc_relayer::channel::error::ChannelError;
use ibc_relayer::connection::ConnectionError;
use ibc_relayer::error::Error as RelayerError;
use ibc_relayer::link::error::LinkError;
use ibc_relayer::supervisor::error::Error as SupervisorError;
use ibc_relayer::transfer::TransferError;
use std::io::{Error as IoError, ErrorKind as IoErrorKind};

define_error! {
    Error {
        Generic
            [ TraceError<Report> ]
            | _ | { "generic error" },

        Assertion
            { message: String }
            | e | { format_args!("assertion failure: {}", e.message) },

        Io
            [ TraceError<IoError> ]
            | _ | { "io error"},

        CommandNotFound
            { command: String }
            [ TraceError<IoError> ]
            | e | { format_args!("failed to execute command: {}. make sure it is available in $PATH", e.command) },

        Relayer
            [ RelayerError ]
            | _ | { "relayer error"},

        Supervisor
            [ SupervisorError ]
            | _ | { "supervisor error"},

        Channel
            [ ChannelError ]
            | _ | { "channel error"},

        Connection
            [ ConnectionError ]
            | _ | { "connection error"},

        Transfer
            [ TransferError ]
            | _ | { "transfer error"},

        Link
            [ LinkError ]
            | _ | { "link error" },

        Retry
            {
                task_name: String,
                attempts: u16,
            }
            | e | {
                format_args!(
                    "Expected task to eventually succeeed, but failed after {} attempts: {}",
                    e.attempts,
                    e.task_name
                )
            },
    }
}

pub fn handle_generic_error(e: impl Into<Report>) -> Error {
    Error::generic(e.into())
}

pub fn handle_exec_error(command: &str) -> impl FnOnce(IoError) -> Error + '_ {
    |e| match e.kind() {
        IoErrorKind::NotFound => Error::command_not_found(command.to_string(), e),
        _ => Error::io(e),
    }
}

impl From<Report> for Error {
    fn from(e: Report) -> Self {
        Error::generic(e)
    }
}

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

impl From<RelayerError> for Error {
    fn from(e: RelayerError) -> Self {
        Error::relayer(e)
    }
}

impl From<SupervisorError> for Error {
    fn from(e: SupervisorError) -> Self {
        Error::supervisor(e)
    }
}

impl From<ChannelError> for Error {
    fn from(e: ChannelError) -> Self {
        Error::channel(e)
    }
}

impl From<ConnectionError> for Error {
    fn from(e: ConnectionError) -> Self {
        Error::connection(e)
    }
}

impl From<TransferError> for Error {
    fn from(e: TransferError) -> Self {
        Error::transfer(e)
    }
}

impl From<LinkError> for Error {
    fn from(e: LinkError) -> Self {
        Error::link(e)
    }
}