Skip to main content

rialo_feature_management_interface/
error.rs

1// Copyright (c) Subzero Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Error types for the Feature Management Program
5
6use rialo_s_instruction::error::InstructionError;
7use rialo_s_program_error::{PrintProgramError, ProgramError};
8
9/// Errors that can be returned by the Feature Management Program
10///
11/// **Stable from this commit forward.** Discriminants surface as
12/// `ProgramError::Custom(u32)` over the wire, so reordering or renumbering
13/// silently shifts what external decoders see. Pre-launch this enum has
14/// been compacted to fill the gaps left by the dropped sticky/windowed
15/// variants; from now on, add new variants only at the tail with the next
16/// unused discriminant.
17#[derive(Debug, Clone, PartialEq, Eq)]
18#[repr(u32)]
19pub enum FeatureManagementError {
20    /// Unauthorized access - signature verification failed
21    Unauthorized = 0,
22
23    /// Invalid feature name (empty or too long)
24    InvalidFeatureName = 1,
25
26    /// Feature not found
27    FeatureNotFound = 2,
28
29    /// Serialization error
30    SerializationError = 3,
31
32    /// Deserialization error
33    DeserializationError = 4,
34
35    /// Invalid instruction data
36    InvalidInstructionData = 5,
37
38    /// Internal error (e.g., mutex lock failure)
39    InternalError = 6,
40
41    /// Duplicate feature in modification list
42    DuplicateFeature = 7,
43
44    /// Invalid storage account (not the expected PDA)
45    InvalidStorageAccount = 8,
46
47    /// Storage account already initialized
48    AlreadyInitialized = 9,
49
50    /// Storage account not initialized
51    NotInitialized = 10,
52
53    /// Maximum feature count exceeded.
54    MaxFeatureCountExceeded = 11,
55
56    /// A single `Enable` instruction submitted more names than
57    /// `MAX_NAMES_PER_BATCH` permits.
58    TooManyNames = 12,
59
60    /// `AcceptAuthorityTransfer` / `CancelAuthorityTransfer` invoked while
61    /// no transfer is pending.
62    NoPendingTransfer = 13,
63
64    /// `ProposeAuthorityTransfer` invoked while a previous proposal is
65    /// still outstanding. Cancel the existing proposal first.
66    PendingTransferExists = 14,
67
68    /// `ProposeAuthorityTransfer` invoked with `new_authority` equal to the
69    /// current authority. Distinct from `Unauthorized` — the signer IS the
70    /// authority; the *target* of the transfer is degenerate.
71    InvalidTransferTarget = 15,
72
73    /// `ScheduleEnable` invoked with a `fire_at_ms` at or before the current
74    /// block time. A schedule must activate in the future; use `Enable` for
75    /// immediate activation.
76    ScheduleInPast = 16,
77
78    /// `ScheduleEnable` invoked with a `fire_at_ms` more than
79    /// `MAX_SCHEDULE_HORIZON_MS` past the current block time. Guards against
80    /// fat-fingered far-future timestamps (e.g. seconds mistaken for millis).
81    ScheduleTooFarOut = 17,
82
83    /// `Cancel` invoked with a `request_id` that has no pending entry —
84    /// already fired, already cancelled, or never existed.
85    RequestNotFound = 18,
86
87    /// `ScheduleEnable` invoked while the pending set is already at
88    /// `MAX_PENDING_REQUESTS`. Cancel or let existing schedules fire first.
89    TooManyPendingRequests = 19,
90
91    /// `ScheduleEnable` invoked with a `request_id` that already has a pending
92    /// entry.
93    RequestAlreadyExists = 20,
94
95    /// `ScheduleEnable` whose new pending entry would push the serialized
96    /// `FeaturesState` over `MAX_FEATURES_STATE_SIZE`. The byte budget — not
97    /// `MAX_PENDING_REQUESTS` — is the binding cap once requests carry
98    /// non-trivial batches, so this is surfaced explicitly rather than as a
99    /// bare `SerializationError` at save time.
100    PendingStateTooLarge = 21,
101}
102
103impl From<FeatureManagementError> for ProgramError {
104    fn from(e: FeatureManagementError) -> Self {
105        ProgramError::Custom(e as u32)
106    }
107}
108
109impl From<FeatureManagementError> for InstructionError {
110    fn from(e: FeatureManagementError) -> Self {
111        InstructionError::Custom(e as u32)
112    }
113}
114
115impl PrintProgramError for FeatureManagementError {
116    fn print<E>(&self) {}
117}