fedimint_gateway_server/
error.rs
1use std::fmt::Display;
2
3use axum::response::{IntoResponse, Response};
4use fedimint_core::config::{FederationId, FederationIdPrefix};
5use fedimint_core::crit;
6use fedimint_core::envs::is_env_var_set;
7use fedimint_core::fmt_utils::OptStacktrace;
8use fedimint_gw_client::pay::OutgoingPaymentError;
9use fedimint_lightning::LightningRpcError;
10use fedimint_logging::LOG_GATEWAY;
11use reqwest::StatusCode;
12use thiserror::Error;
13
14use crate::envs::FM_DEBUG_GATEWAY_ENV;
15
16#[derive(Debug, Error)]
20pub enum PublicGatewayError {
21 #[error("Lightning rpc error: {}", .0)]
22 Lightning(#[from] LightningRpcError),
23 #[error("LNv1 error: {:?}", .0)]
24 LNv1(#[from] LNv1Error),
25 #[error("LNv2 error: {:?}", .0)]
26 LNv2(#[from] LNv2Error),
27 #[error("{}", .0)]
28 FederationNotConnected(#[from] FederationNotConnected),
29 #[error("Failed to receive ecash: {failure_reason}")]
30 ReceiveEcashError { failure_reason: String },
31}
32
33impl IntoResponse for PublicGatewayError {
34 fn into_response(self) -> Response {
35 crit!(target: LOG_GATEWAY, "{self}");
39 let (error_message, status_code) = match &self {
40 PublicGatewayError::FederationNotConnected(e) => {
41 (e.to_string(), StatusCode::BAD_REQUEST)
42 }
43 PublicGatewayError::ReceiveEcashError { .. } => (
44 "Failed to receive ecash".to_string(),
45 StatusCode::INTERNAL_SERVER_ERROR,
46 ),
47 PublicGatewayError::Lightning(_) => (
48 "Lightning Network operation failed".to_string(),
49 StatusCode::INTERNAL_SERVER_ERROR,
50 ),
51 PublicGatewayError::LNv1(_) => (
52 "LNv1 operation failed, please contact gateway operator".to_string(),
53 StatusCode::INTERNAL_SERVER_ERROR,
54 ),
55 PublicGatewayError::LNv2(_) => (
56 "LNv2 operation failed, please contact gateway operator".to_string(),
57 StatusCode::INTERNAL_SERVER_ERROR,
58 ),
59 };
60
61 let error_message = if is_env_var_set(FM_DEBUG_GATEWAY_ENV) {
62 self.to_string()
63 } else {
64 error_message
65 };
66
67 Response::builder()
68 .status(status_code)
69 .body(error_message.into())
70 .expect("Failed to create Response")
71 }
72}
73
74#[derive(Debug, Error)]
77pub enum AdminGatewayError {
78 #[error("Failed to create a federation client: {}", OptStacktrace(.0))]
79 ClientCreationError(anyhow::Error),
80 #[error("Failed to remove a federation client: {}", OptStacktrace(.0))]
81 ClientRemovalError(String),
82 #[error("There was an error with the Gateway's mnemonic: {}", OptStacktrace(.0))]
83 MnemonicError(anyhow::Error),
84 #[error("Unexpected Error: {}", OptStacktrace(.0))]
85 Unexpected(#[from] anyhow::Error),
86 #[error("{}", .0)]
87 FederationNotConnected(#[from] FederationNotConnected),
88 #[error("Error configuring the gateway: {}", OptStacktrace(.0))]
89 GatewayConfigurationError(String),
90 #[error("Lightning error: {}", OptStacktrace(.0))]
91 Lightning(#[from] LightningRpcError),
92 #[error("Error registering federation {federation_id}")]
93 RegistrationError { federation_id: FederationId },
94 #[error("Error withdrawing funds onchain: {failure_reason}")]
95 WithdrawError { failure_reason: String },
96}
97
98impl IntoResponse for AdminGatewayError {
99 fn into_response(self) -> Response {
102 crit!(target: LOG_GATEWAY, "{self}");
103 Response::builder()
104 .status(StatusCode::INTERNAL_SERVER_ERROR)
105 .body(self.to_string().into())
106 .expect("Failed to create Response")
107 }
108}
109
110#[derive(Debug, Error)]
113pub enum LNv1Error {
114 #[error("Incoming payment error: {}", OptStacktrace(.0))]
115 IncomingPayment(String),
116 #[error(
117 "Outgoing Contract Error Reason: {message} Stack: {}",
118 OptStacktrace(error)
119 )]
120 OutgoingContract {
121 error: Box<OutgoingPaymentError>,
122 message: String,
123 },
124 #[error("Outgoing Payment Error: {}", OptStacktrace(.0))]
125 OutgoingPayment(#[from] anyhow::Error),
126}
127
128#[derive(Debug, Error)]
131pub enum LNv2Error {
132 #[error("Incoming Payment Error: {}", .0)]
133 IncomingPayment(String),
134 #[error("Outgoing Payment Error: {}", OptStacktrace(.0))]
135 OutgoingPayment(#[from] anyhow::Error),
136}
137
138#[derive(Debug, Error)]
141pub struct FederationNotConnected {
142 pub federation_id_prefix: FederationIdPrefix,
143}
144
145impl Display for FederationNotConnected {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147 write!(
148 f,
149 "No federation available for prefix {}",
150 self.federation_id_prefix
151 )
152 }
153}