zlicenser_server/
error.rs1#[derive(Debug, thiserror::Error)]
2pub enum Error {
3 #[error("record not found")]
4 NotFound,
5 #[error("unique constraint violation: {0}")]
6 Conflict(String),
7 #[error("foreign key constraint violation: {0}")]
8 ForeignKeyViolation(String),
9 #[error("database error: {0}")]
10 Database(String),
11 #[error("migration error: {0}")]
12 Migration(String),
13 #[error("corrupt stored data: {0}")]
14 Corrupt(String),
15
16 #[error("the license offer has expired; begin a new enrollment")]
17 OfferExpired,
18 #[error("no enrollment session found with the given identifier")]
19 SessionNotFound,
20 #[error("invalid state machine transition: {0}")]
21 InvalidTransition(String),
22 #[error("all seat slots for this license are occupied")]
23 SeatLimitReached,
24 #[error("payment intent is not in the RequiresCapture state")]
25 PaymentNotHeld,
26 #[error("TSA timestamping failed after all retries: {0}")]
27 TsaFailed(String),
28 #[error("payment capture failed: {0}")]
29 PaymentCaptureFailed(String),
30 #[error("payment cancellation failed: {0}")]
31 PaymentCancelFailed(String),
32 #[error("revocation is not supported for air-gapped licenses")]
33 RevocationNotSupported,
34 #[error("client version {got} is below the required minimum {required}")]
35 ClientVersionRejected { required: String, got: String },
36 #[error("offer nonce in receipt does not match the session")]
37 OfferNonceMismatch,
38 #[error("consent record is invalid: {0}")]
39 ConsentInvalid(String),
40 #[error("a transfer request is already pending for this license")]
41 TransferAlreadyPending,
42 #[error("the customer's signature on the receipt is invalid")]
43 InvalidReceiptSignature,
44 #[error("product is not accepting new enrollments")]
45 ProductInactive,
46 #[error("no active fingerprint binding found for this hardware on this license")]
47 BindingNotFound,
48 #[error("secret wrapping failed: {0}")]
49 SecretWrappingFailed(String),
50 #[error("no payment provider configured for this product")]
51 NoPaymentProvider,
52}
53
54#[cfg(feature = "storage-sqlite")]
55impl From<sqlx::Error> for Error {
56 fn from(e: sqlx::Error) -> Self {
57 match &e {
58 sqlx::Error::RowNotFound => Error::NotFound,
59 sqlx::Error::Database(db) => {
60 let msg = db.message().to_string();
61 if db.is_unique_violation() {
62 Error::Conflict(msg)
63 } else if db.is_foreign_key_violation() || msg.contains("FOREIGN KEY") {
64 Error::ForeignKeyViolation(msg)
65 } else {
66 Error::Database(msg)
67 }
68 }
69 _ => Error::Database(e.to_string()),
70 }
71 }
72}
73
74#[cfg(all(feature = "storage-postgres", not(feature = "storage-sqlite")))]
75impl From<sqlx::Error> for Error {
76 fn from(e: sqlx::Error) -> Self {
77 match &e {
78 sqlx::Error::RowNotFound => Error::NotFound,
79 sqlx::Error::Database(db) => {
80 let msg = db.message().to_string();
81 if db.is_unique_violation() {
82 Error::Conflict(msg)
83 } else if db.is_foreign_key_violation() {
84 Error::ForeignKeyViolation(msg)
85 } else {
86 Error::Database(msg)
87 }
88 }
89 _ => Error::Database(e.to_string()),
90 }
91 }
92}