kaccy_reputation/error.rs
1//! Reputation error types
2
3use rust_decimal::Decimal;
4use thiserror::Error;
5
6/// All error types for the reputation system.
7#[derive(Error, Debug)]
8pub enum ReputationError {
9 // Database errors
10 /// Underlying database error.
11 #[error("Database error: {0}")]
12 Database(#[from] sqlx::Error),
13
14 // Validation errors
15 /// A field or parameter failed validation.
16 #[error("Validation error: {0}")]
17 Validation(String),
18
19 /// Supplied rating value is outside the allowed range.
20 #[error("Invalid rating: {0}")]
21 InvalidRating(String),
22
23 /// Score delta exceeds the maximum allowed single-event change.
24 #[error("Invalid score delta: {delta}, max allowed: {max_allowed}")]
25 InvalidScoreDelta {
26 /// The supplied delta value.
27 delta: Decimal,
28 /// The maximum permitted delta for a single event.
29 max_allowed: Decimal,
30 },
31
32 /// An entity cannot transition to the requested state from its current state.
33 #[error("Invalid state transition: from {from} to {to}")]
34 InvalidStateTransition {
35 /// Current state.
36 from: String,
37 /// Attempted target state.
38 to: String,
39 },
40
41 // Not found errors
42 /// Requested user was not found.
43 #[error("User not found: {0}")]
44 UserNotFound(String),
45
46 /// Requested commitment was not found.
47 #[error("Commitment not found: {0}")]
48 CommitmentNotFound(String),
49
50 /// Requested token was not found.
51 #[error("Token not found: {0}")]
52 TokenNotFound(String),
53
54 /// Requested dispute was not found.
55 #[error("Dispute not found: {0}")]
56 DisputeNotFound(String),
57
58 /// No SBT exists for the requested user.
59 #[error("SBT not found for user: {0}")]
60 SBTNotFound(String),
61
62 // Authorization errors
63 /// The caller lacks permission to perform this action.
64 #[error("Unauthorized: {0}")]
65 Unauthorized(String),
66
67 /// A token holder attempted to rate a token they issued.
68 #[error("Cannot rate own token")]
69 CannotRateOwnToken,
70
71 /// Token holder's balance is below the minimum required to submit a rating.
72 #[error("Insufficient balance to rate: required {required}, current {current}")]
73 InsufficientBalance {
74 /// Minimum balance required to rate.
75 required: Decimal,
76 /// Caller's current balance.
77 current: Decimal,
78 },
79
80 /// Token holder has not held the token long enough to rate.
81 #[error("Insufficient holding duration: required {required_hours}h, held for {held_hours}h")]
82 InsufficientHoldingDuration {
83 /// Minimum holding duration required in hours.
84 required_hours: i64,
85 /// How long the caller has held the token in hours.
86 held_hours: i64,
87 },
88
89 // Reputation errors
90 /// User's reputation triggered the circuit breaker, blocking the operation.
91 #[error("Circuit breaker triggered for user: {0}")]
92 CircuitBreakerTriggered(String),
93
94 /// User's reputation score is below the minimum required for this operation.
95 #[error("Insufficient reputation: required {required}, current {current}")]
96 InsufficientReputation {
97 /// Required reputation score.
98 required: Decimal,
99 /// User's current reputation score.
100 current: Decimal,
101 },
102
103 /// User is not permitted to issue tokens due to reputation constraints.
104 #[error("Cannot issue tokens: {0}")]
105 CannotIssueTokens(String),
106
107 // Commitment errors
108 /// The commitment has already been verified and cannot be verified again.
109 #[error("Commitment already verified")]
110 CommitmentAlreadyVerified,
111
112 /// The commitment's deadline has passed.
113 #[error("Commitment deadline expired")]
114 CommitmentDeadlineExpired,
115
116 /// Evidence must be submitted before this commitment can be verified.
117 #[error("Evidence required for commitment verification")]
118 EvidenceRequired,
119
120 // Dispute errors
121 /// The dispute has already been resolved and cannot be modified.
122 #[error("Dispute already resolved")]
123 DisputeAlreadyResolved,
124
125 /// The dispute's voting period has ended; no more votes can be cast.
126 #[error("Voting period ended")]
127 VotingPeriodEnded,
128
129 /// The dispute's voting period has not yet ended.
130 #[error("Voting period not yet ended")]
131 VotingPeriodNotEnded,
132
133 /// User has already cast a vote on this dispute.
134 #[error("User already voted on this dispute")]
135 AlreadyVoted,
136
137 /// User's voting power is below the minimum required to vote on this dispute.
138 #[error("Insufficient voting power: required {required}, current {current}")]
139 InsufficientVotingPower {
140 /// Required voting power.
141 required: Decimal,
142 /// User's current voting power.
143 current: Decimal,
144 },
145
146 // SBT errors
147 /// SBT already minted for this user; minting is idempotent.
148 #[error("SBT already minted for user: {0}")]
149 SBTAlreadyMinted(String),
150
151 /// SBT has not yet been minted for this user.
152 #[error("SBT not yet minted for user: {0}")]
153 SBTNotMinted(String),
154}
155
156/// Convenience alias for `std::result::Result<T, ReputationError>`.
157pub type Result<T> = std::result::Result<T, ReputationError>;