switchgear_service/components/pool/
error.rs1use crate::api::service::{HasServiceErrorSource, ServiceErrorSource};
2use std::borrow::Cow;
3use std::fmt::{Display, Formatter};
4use thiserror::Error;
5use tonic::{transport, Code, Status};
6
7#[derive(Error, Debug)]
8pub enum LnPoolErrorSourceKind {
9 #[error("CLN tonic gRPC error: {0}")]
10 TonicError(Status),
11 #[error("CLN transport connection error: {0}")]
12 TransportError(transport::Error),
13 #[error("invalid configuration for: {0}")]
14 InvalidConfiguration(String),
15 #[error("invalid credentials for {0}")]
16 InvalidCredentials(String),
17 #[error("memory error: {0}")]
18 MemoryError(String),
19}
20
21#[derive(Error, Debug)]
22pub struct LnPoolError {
23 context: Cow<'static, str>,
24 #[source]
25 source: LnPoolErrorSourceKind,
26 esource: ServiceErrorSource,
27}
28
29impl Display for LnPoolError {
30 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
31 write!(
32 f,
33 "LnPoolError: while {}: {}",
34 self.context.as_ref(),
35 self.source
36 )
37 }
38}
39
40impl LnPoolError {
41 fn new<C: Into<Cow<'static, str>>>(
42 source: LnPoolErrorSourceKind,
43 esource: ServiceErrorSource,
44 context: C,
45 ) -> Self {
46 Self {
47 context: context.into(),
48 source,
49 esource,
50 }
51 }
52
53 pub fn from_invalid_configuration<C: Into<Cow<'static, str>>>(
54 source: C,
55 esource: ServiceErrorSource,
56 context: C,
57 ) -> Self {
58 Self::new(
59 LnPoolErrorSourceKind::InvalidConfiguration(source.into().to_string()),
60 esource,
61 context.into(),
62 )
63 }
64
65 pub fn from_invalid_credentials<C: Into<Cow<'static, str>>>(
66 source: C,
67 esource: ServiceErrorSource,
68 context: C,
69 ) -> Self {
70 Self::new(
71 LnPoolErrorSourceKind::InvalidCredentials(source.into().to_string()),
72 esource,
73 context.into(),
74 )
75 }
76
77 pub fn from_tonic_error<C: Into<Cow<'static, str>>>(source: Status, context: C) -> Self {
78 let esource = Self::from_tonic_code(source.code());
79 Self::new(LnPoolErrorSourceKind::TonicError(source), esource, context)
80 }
81
82 pub fn from_transport_error<C: Into<Cow<'static, str>>>(
83 source: transport::Error,
84 esource: ServiceErrorSource,
85 context: C,
86 ) -> Self {
87 Self::new(
88 LnPoolErrorSourceKind::TransportError(source),
89 esource,
90 context,
91 )
92 }
93
94 pub fn from_memory_error<C: Into<Cow<'static, str>>>(source: String, context: C) -> Self {
95 Self::new(
96 LnPoolErrorSourceKind::MemoryError(source),
97 ServiceErrorSource::Internal,
98 context,
99 )
100 }
101
102 pub fn context(&self) -> &str {
103 self.context.as_ref()
104 }
105
106 pub fn source(&self) -> &LnPoolErrorSourceKind {
107 &self.source
108 }
109
110 pub fn esource(&self) -> ServiceErrorSource {
111 self.esource
112 }
113
114 fn from_tonic_code(code: Code) -> ServiceErrorSource {
115 match code {
116 Code::InvalidArgument | Code::OutOfRange | Code::AlreadyExists => {
117 ServiceErrorSource::Downstream
118 }
119
120 _ => ServiceErrorSource::Upstream,
121 }
122 }
123}
124
125impl HasServiceErrorSource for LnPoolError {
126 fn get_service_error_source(&self) -> ServiceErrorSource {
127 self.esource
128 }
129}