Skip to main content

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>;