brane_reg/
errors.rs

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
//  ERRORS.rs
//    by Lut99
//
//  Created:
//    26 Sep 2022, 15:13:34
//  Last edited:
//    16 Jan 2024, 17:27:57
//  Auto updated?
//    Yes
//
//  Description:
//!   Defines the errors that may occur in the `brane-reg` crate.
//

use std::error::Error;
use std::fmt::{Display, Formatter, Result as FResult};
use std::net::SocketAddr;
use std::path::PathBuf;


/***** LIBRARY *****/
/// Defines Store-related errors.
#[derive(Debug)]
pub enum StoreError {
    /// Failed to parse from the given reader.
    ReaderParseError { err: serde_yaml::Error },

    /// Failed to open the store file.
    FileOpenError { path: PathBuf, err: std::io::Error },
    /// Failed to parse the store file.
    FileParseError { path: PathBuf, err: serde_yaml::Error },

    /// Failed to read the given directory.
    DirReadError { path: PathBuf, err: std::io::Error },
    /// Failed to read an entry in the given directory.
    DirReadEntryError { path: PathBuf, i: usize, err: std::io::Error },
    /// Failed to read the AssetInfo file.
    AssetInfoReadError { path: PathBuf, err: specifications::data::AssetInfoError },
}

impl Display for StoreError {
    fn fmt(&self, f: &mut Formatter<'_>) -> FResult {
        use StoreError::*;
        match self {
            ReaderParseError { .. } => write!(f, "Failed to parse the given store reader as YAML"),

            FileOpenError { path, .. } => write!(f, "Failed to open store file '{}'", path.display()),
            FileParseError { path, .. } => write!(f, "Failed to parse store file '{}' as YAML", path.display()),

            DirReadError { path, .. } => write!(f, "Failed to read directory '{}'", path.display()),
            DirReadEntryError { path, i, .. } => write!(f, "Failed to read entry {} in directory '{}'", i, path.display()),
            AssetInfoReadError { path, .. } => write!(f, "Failed to load asset info file '{}'", path.display()),
        }
    }
}

impl Error for StoreError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use StoreError::*;
        match self {
            ReaderParseError { err } => Some(err),

            FileOpenError { err, .. } => Some(err),
            FileParseError { err, .. } => Some(err),

            DirReadError { err, .. } => Some(err),
            DirReadEntryError { err, .. } => Some(err),
            AssetInfoReadError { err, .. } => Some(err),
        }
    }
}



/// Errors that relate to the customized serving process of warp.
#[derive(Debug)]
pub enum ServerError {
    /// Failed to create a new TcpListener and bind it to the given address.
    ServerBindError { address: SocketAddr, err: std::io::Error },
    /// Failed to load the keypair.
    KeypairLoadError { err: brane_cfg::certs::Error },
    /// Failed to load the certificate root store.
    StoreLoadError { err: brane_cfg::certs::Error },
    /// Failed to create a new ServerConfig for the TLS setup.
    ServerConfigError { err: rustls::Error },
}

impl Display for ServerError {
    fn fmt(&self, f: &mut Formatter<'_>) -> FResult {
        use ServerError::*;
        match self {
            ServerBindError { address, .. } => write!(f, "Failed to bind new TCP server to '{address}'"),
            KeypairLoadError { .. } => write!(f, "Failed to load keypair"),
            StoreLoadError { .. } => write!(f, "Failed to load root store"),
            ServerConfigError { .. } => write!(f, "Failed to create new TLS server configuration"),
        }
    }
}

impl Error for ServerError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use ServerError::*;
        match self {
            ServerBindError { err, .. } => Some(err),
            KeypairLoadError { err } => Some(err),
            StoreLoadError { err } => Some(err),
            ServerConfigError { err } => Some(err),
        }
    }
}



/// Errors that relate to the `/data` path (and nested).
#[derive(Debug)]
pub enum DataError {
    /// Failed to serialize the contents of the store file (i.e., all known datasets)
    StoreSerializeError { err: serde_json::Error },
    /// Failed to serialize the contents of a single dataset.
    AssetSerializeError { name: String, err: serde_json::Error },

    /// Failed to create a temporary directory.
    TempDirCreateError { err: std::io::Error },
    /// Failed to archive the given dataset.
    DataArchiveError { err: brane_shr::fs::Error },
    /// Failed to re-open the tar file after compressing.
    TarOpenError { path: PathBuf, err: std::io::Error },
    /// Failed to read from the tar file.
    TarReadError { path: PathBuf, err: std::io::Error },
    /// Failed to send chunk of bytes on the body.
    TarSendError { err: warp::hyper::Error },
    /// The given file was not a file, nor a directory.
    UnknownFileTypeError { path: PathBuf },
    /// The given data path does not point to a data set, curiously enough.
    MissingData { name: String, path: PathBuf },
    /// The given result does not point to a data set, curiously enough.
    MissingResult { name: String, path: PathBuf },
}

impl Display for DataError {
    fn fmt(&self, f: &mut Formatter<'_>) -> FResult {
        use DataError::*;
        match self {
            StoreSerializeError { .. } => write!(f, "Failed to serialize known datasets"),
            AssetSerializeError { name, .. } => write!(f, "Failed to serialize dataset metadata for dataset '{name}'"),

            TempDirCreateError { .. } => write!(f, "Failed to create a temporary directory"),
            DataArchiveError { .. } => write!(f, "Failed to archive data"),
            TarOpenError { path, .. } => write!(f, "Failed to re-open tarball file '{}'", path.display()),
            TarReadError { path, .. } => write!(f, "Failed to read from tarball file '{}'", path.display()),
            TarSendError { .. } => write!(f, "Failed to send chunk of tarball file as body"),
            UnknownFileTypeError { path } => {
                write!(f, "Dataset file '{}' is neither a file, nor a directory; don't know what to do with it", path.display())
            },
            MissingData { name, path } => write!(f, "The data of dataset '{}' should be at '{}', but doesn't exist", name, path.display()),
            MissingResult { name, path } => {
                write!(f, "The data of intermediate result '{}' should be at '{}', but doesn't exist", name, path.display())
            },
        }
    }
}

impl Error for DataError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use DataError::*;
        match self {
            StoreSerializeError { err } => Some(err),
            AssetSerializeError { err, .. } => Some(err),

            TempDirCreateError { err } => Some(err),
            DataArchiveError { err } => Some(err),
            TarOpenError { err, .. } => Some(err),
            TarReadError { err, .. } => Some(err),
            TarSendError { err, .. } => Some(err),
            UnknownFileTypeError { .. } => None,
            MissingData { .. } => None,
            MissingResult { .. } => None,
        }
    }
}

impl warp::reject::Reject for DataError {}



/// Errors that relate to checker authorization.
#[derive(Debug)]
pub enum AuthorizeError {
    /// The client did not provide us with a certificate.
    ClientNoCert,

    /// Failed to load the policy file.
    PolicyFileError { err: brane_cfg::policies::Error },
    /// No policy matched this user/data pair.
    NoUserPolicy { user: String, data: String },
}

impl Display for AuthorizeError {
    fn fmt(&self, f: &mut Formatter<'_>) -> FResult {
        use AuthorizeError::*;
        match self {
            ClientNoCert => write!(f, "No certificate provided"),

            PolicyFileError { .. } => write!(f, "Failed to load policy file"),
            NoUserPolicy { user, data } => {
                write!(f, "No matching policy rule found for user '{user}' / data '{data}' (did you forget a final AllowAll/DenyAll?)")
            },
        }
    }
}

impl Error for AuthorizeError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use AuthorizeError::*;
        match self {
            ClientNoCert => None,

            PolicyFileError { err } => Some(err),
            NoUserPolicy { .. } => None,
        }
    }
}