Skip to main content

nym_sdk/
error.rs

1// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use nym_ip_packet_requests::v8::response::{ConnectFailureReason, IpPacketResponseData};
5use nym_validator_client::nym_api::error::NymAPIError;
6use nym_validator_client::nyxd::error::NyxdError;
7use std::path::PathBuf;
8
9/// Top-level Error enum for the mixnet client and its relevant types.
10#[derive(Debug, thiserror::Error)]
11pub enum Error {
12    #[error("i/o error: {0}")]
13    IoError(#[from] std::io::Error),
14
15    #[error("toml serialization error: {0}")]
16    TomlSerializationError(#[from] toml::ser::Error),
17
18    #[error("toml deserialization error: {0}")]
19    TomlDeserializationError(#[from] toml::de::Error),
20
21    #[error("Ed25519 error: {0}")]
22    Ed25519RecoveryError(#[from] nym_crypto::asymmetric::ed25519::Ed25519RecoveryError),
23
24    #[error(transparent)]
25    ClientCoreError(#[from] nym_client_core::error::ClientCoreError),
26
27    #[error("key file encountered that we don't want to overwrite: {0}")]
28    DontOverwrite(PathBuf),
29
30    #[error("shared gateway key file encountered that we don't want to overwrite: {0}")]
31    DontOverwriteGatewayKey(PathBuf),
32
33    #[error("no gateway config available for writing")]
34    GatewayNotAvailableForWriting,
35
36    #[error("expected to received a directory, received: {0}")]
37    ExpectedDirectory(PathBuf),
38
39    #[error("failed to transition to registered state before connection to mixnet")]
40    FailedToTransitionToRegisteredState,
41
42    #[error(
43        "registering with gateway when the client is already in a registered state is not \
44         supported, and likely and user mistake"
45    )]
46    ReregisteringGatewayNotSupported,
47
48    #[error("no gateway key set")]
49    NoGatewayKeySet,
50
51    #[error("credentials mode not enabled")]
52    DisabledCredentialsMode,
53
54    #[error("bad validator details: {0}")]
55    BadValidatorDetails(#[from] NyxdError),
56
57    #[error("socks5 configuration set: {}, but expected to be {}", set, !set)]
58    Socks5Config { set: bool },
59
60    #[error("socks5 channel could not be started")]
61    Socks5NotStarted,
62
63    #[error("bandwidth controller error: {0}")]
64    BandwidthControllerError(#[from] nym_bandwidth_controller::error::BandwidthControllerError),
65
66    #[error("invalid voucher blob")]
67    InvalidVoucherBlob,
68
69    #[error("invalid mnemonic: {0}")]
70    InvalidMnemonic(#[from] bip39::Error),
71
72    #[error("failed to use reply storage backend: {source}")]
73    ReplyStorageError {
74        source: Box<dyn std::error::Error + Send + Sync>,
75    },
76
77    #[error("failed to use key storage backend: {source}")]
78    KeyStorageError {
79        source: Box<dyn std::error::Error + Send + Sync>,
80    },
81
82    #[error("failed to use credential storage backend: {source}")]
83    CredentialStorageError {
84        source: Box<dyn std::error::Error + Send + Sync>,
85    },
86
87    #[error("loaded shared gateway key without providing information about what gateway it corresponds to")]
88    GatewayWithUnknownEndpoint,
89
90    #[error("failed to send the provided message")]
91    MessageSendingFailure,
92
93    #[error("this operation is currently unsupported: {details}")]
94    Unsupported { details: String },
95
96    #[error(transparent)]
97    Bincode(#[from] bincode::Error),
98
99    #[error("Failed to get shutdown tracker from the task runtime registry: {0}")]
100    RegistryAccess(#[from] nym_task::RegistryAccessError),
101
102    #[error("Cannot use message-based functions after stream mode is activated")]
103    StreamModeActive,
104
105    #[error("Stream listener has already been taken — listener() can only be called once")]
106    ListenerAlreadyTaken,
107
108    #[error("Stream subsystem failed to initialise: reconstructed_receiver unavailable")]
109    StreamInitFailure,
110
111    #[error("client not connected")]
112    IprStreamClientNotConnected,
113
114    #[error("listening for connection response timed out")]
115    IPRConnectResponseTimeout,
116
117    #[error("stream closed")]
118    IPRClientStreamClosed,
119
120    #[error("expected control response, got {0:?}")]
121    UnexpectedResponseType(IpPacketResponseData),
122
123    #[error("connect denied: {0:?}")]
124    ConnectDenied(ConnectFailureReason),
125
126    #[allow(clippy::result_large_err)]
127    #[error("api directory error: {0}")]
128    GatewayDirectoryError(#[from] NymAPIError),
129
130    #[error("did not receive Nym API URL")]
131    NoNymAPIUrl,
132
133    #[error("no available gateway")]
134    NoGatewayAvailable,
135
136    #[error("invalid ISO 3166 alpha-2 country code: {0}")]
137    InvalidCountryCode(String),
138
139    #[error("no available gateway in the requested countries")]
140    NoGatewayInCountries,
141
142    #[error("no countries specified; use NetworkRequesterSelector::any() to accept any country")]
143    NoCountriesSpecified,
144
145    #[error("invalid network requester address: {0}")]
146    InvalidRecipientAddress(String),
147
148    #[error("tunnel disconnected by IPR")]
149    IprTunnelDisconnected,
150
151    #[error("message version check failed: {0}")]
152    IPRMessageVersionCheckFailed(String),
153}
154
155impl Error {
156    pub fn new_unsupported<S: Into<String>>(details: S) -> Self {
157        Error::Unsupported {
158            details: details.into(),
159        }
160    }
161}
162
163/// A [`Result`](std::result::Result) type alias with [`Error`] as the default error type.
164pub type Result<T, E = Error> = std::result::Result<T, E>;