iota_aws_orchestrator/
error.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::net::SocketAddr;
6
7use reqwest::Url;
8
9#[macro_export(local_inner_macros)]
10macro_rules! ensure {
11    ($cond:expr, $e:expr) => {
12        if !($cond) {
13            return Err($e);
14        }
15    };
16}
17
18pub type SettingsResult<T> = Result<T, SettingsError>;
19
20#[derive(thiserror::Error, Debug)]
21pub enum SettingsError {
22    #[error("Failed to read settings file '{file:?}': {message}")]
23    InvalidSettings { file: String, message: String },
24
25    #[error("Failed to read token file '{file:?}': {message}")]
26    InvalidTokenFile { file: String, message: String },
27
28    #[error("Failed to read ssh public key file '{file:?}': {message}")]
29    InvalidSshPublicKeyFile { file: String, message: String },
30
31    #[error("Malformed repository url: {0:?}")]
32    MalformedRepositoryUrl(Url),
33}
34
35pub type CloudProviderResult<T> = Result<T, CloudProviderError>;
36
37#[derive(thiserror::Error, Debug)]
38pub enum CloudProviderError {
39    #[error("Failed to send server request: {0}")]
40    Request(String),
41
42    #[error("Unexpected response: {0}")]
43    UnexpectedResponse(String),
44
45    #[error("Received error status code ({0}): {1}")]
46    FailureResponseCode(String, String),
47
48    #[error("SSH key \"{0}\" not found")]
49    SshKeyNotFound(String),
50}
51
52pub type SshResult<T> = Result<T, SshError>;
53
54#[derive(thiserror::Error, Debug)]
55pub enum SshError {
56    #[error("Failed to load private key for {address}: {error}")]
57    PrivateKeyError {
58        address: SocketAddr,
59        error: russh_keys::Error,
60    },
61
62    #[error("Failed to create ssh session with {address}: {error}")]
63    SessionError {
64        address: SocketAddr,
65        error: russh::Error,
66    },
67
68    #[error("Failed to connect to instance {address}: {error}")]
69    ConnectionError {
70        address: SocketAddr,
71        error: russh::Error,
72    },
73
74    #[error("Remote execution on {address} returned exit code ({code}): {message}")]
75    NonZeroExitCode {
76        address: SocketAddr,
77        code: u32,
78        message: String,
79    },
80}
81
82pub type MonitorResult<T> = Result<T, MonitorError>;
83
84#[derive(thiserror::Error, Debug)]
85pub enum MonitorError {
86    #[error(transparent)]
87    Ssh(#[from] SshError),
88
89    #[error("Failed to start Grafana: {0}")]
90    Grafana(String),
91}
92
93pub type TestbedResult<T> = Result<T, TestbedError>;
94
95#[derive(thiserror::Error, Debug)]
96pub enum TestbedError {
97    #[error(transparent)]
98    Settings(#[from] SettingsError),
99
100    #[error(transparent)]
101    CloudProvider(#[from] CloudProviderError),
102
103    #[error(transparent)]
104    Ssh(#[from] SshError),
105
106    #[error("Not enough instances: missing {0} instances")]
107    InsufficientCapacity(usize),
108
109    #[error(transparent)]
110    Monitor(#[from] MonitorError),
111}