lightning_signer/util/
status.rs1use crate::prelude::*;
2use core::fmt;
3
4#[cfg(feature = "use_backtrace")]
5use backtrace::Backtrace;
6use log::*;
7
8use crate::policy::error::{ValidationError, ValidationErrorKind};
9
10#[derive(Clone)]
12pub struct Status {
13 code: Code,
15 message: String,
17}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum Code {
24 Ok = 0,
26
27 InvalidArgument = 3,
29
30 FailedPrecondition = 9,
32
33 Internal = 13,
35
36 Temporary = 14,
38}
39
40impl Status {
41 pub fn new(code: Code, message: impl Into<String>) -> Self {
43 Status { code, message: message.into() }
44 }
45
46 pub fn code(&self) -> Code {
48 self.code
49 }
50
51 pub fn message(&self) -> &str {
53 &self.message
54 }
55
56 pub fn invalid_argument(message: impl Into<String>) -> Status {
58 Self::new(Code::InvalidArgument, message)
59 }
60
61 pub fn failed_precondition(message: impl Into<String>) -> Status {
63 Self::new(Code::FailedPrecondition, message)
64 }
65
66 pub fn internal(message: impl Into<String>) -> Status {
68 Self::new(Code::Internal, message)
69 }
70
71 pub fn temporary(message: impl Into<String>) -> Status {
73 Self::new(Code::Temporary, message)
74 }
75}
76
77impl fmt::Debug for Status {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 let mut builder = f.debug_struct("Status");
81
82 builder.field("code", &self.code);
83
84 if !self.message.is_empty() {
85 builder.field("message", &self.message);
86 }
87
88 builder.finish()
89 }
90}
91
92impl fmt::Display for Status {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 write!(f, "status: {:?}, message: {:?}", self.code(), self.message())
95 }
96}
97
98#[cfg(feature = "grpc")]
99impl std::error::Error for Status {}
100
101#[cfg(feature = "grpc")]
102use core::convert::TryInto;
103
104#[cfg(feature = "grpc")]
105impl From<Status> for tonic::Status {
106 fn from(s: Status) -> Self {
107 let code = s.code() as i32;
108 tonic::Status::new(code.try_into().unwrap(), s.message())
110 }
111}
112
113pub fn invalid_argument(msg: impl Into<String>) -> Status {
115 let s = msg.into();
116 error!("INVALID ARGUMENT: {}", &s);
117 #[cfg(feature = "use_backtrace")]
118 error!("BACKTRACE:\n{:?}", Backtrace::new());
119 Status::invalid_argument(s)
120}
121
122pub(crate) fn internal_error(msg: impl Into<String>) -> Status {
123 let s = msg.into();
124 error!("INTERNAL ERROR: {}", &s);
125 #[cfg(feature = "use_backtrace")]
126 error!("BACKTRACE:\n{:?}", Backtrace::new());
127 Status::internal(s)
128}
129
130#[allow(unused)]
131pub(crate) fn failed_precondition(msg: impl Into<String>) -> Status {
132 let s = msg.into();
133 error!("FAILED PRECONDITION: {}", &s);
134 Status::failed_precondition(s)
136}
137
138impl From<ValidationError> for Status {
139 fn from(ve: ValidationError) -> Self {
140 let res = match ve.kind {
141 ValidationErrorKind::TemporaryPolicy(ref s) => {
142 warn!("TEMPORARY POLICY ERROR: {}", s);
143 #[cfg(feature = "use_backtrace")]
144 warn!("BACKTRACE:\n{:?}", &ve.resolved_backtrace());
145 Status::temporary(s)
146 }
147 _ => {
148 let s: String = ve.clone().into();
149 error!("FAILED PRECONDITION: {}", &s);
150 #[cfg(feature = "use_backtrace")]
151 error!("BACKTRACE:\n{:?}", &ve.resolved_backtrace());
152 Status::failed_precondition(s)
153 }
154 };
155 res
156 }
157}