commit_wizard/engine/error/
code.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::engine::error::ErrorKind;
6
7pub mod exit_status {
8 pub const USER: i32 = 2;
10 pub const CONFIG: i32 = 10;
12 pub const STATE: i32 = 11;
13 pub const REGISTRY: i32 = 20;
15 pub const GIT: i32 = 21;
16 pub const IO: i32 = 25;
17 pub const PROCESS: i32 = 26;
18 pub const VALIDATION: i32 = 30;
20 pub const RELEASE: i32 = 31;
21 pub const HOOK: i32 = 32;
22 pub const AI: i32 = 33;
23 pub const RUNTIME: i32 = 50;
25}
26
27macro_rules! error_codes {
28 (
29 $(
30 $variant:ident => ($kind:ident, $num:expr, $msg:expr)
31 ),* $(,)?
32 ) => {
33 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
34 pub enum ErrorCode {
35 $($variant),*
36 }
37
38 impl ErrorCode {
39 pub const fn kind(self) -> ErrorKind {
40 match self {
41 $(Self::$variant => ErrorKind::$kind),*
42 }
43 }
44
45 pub const fn message(self) -> &'static str {
46 match self {
47 $(Self::$variant => $msg),*
48 }
49 }
50
51 pub const fn index(self) -> u16 {
52 match self {
53 $(Self::$variant => $num),*
54 }
55 }
56
57 pub const fn numeric(self) -> u16 {
58 self.kind().prefix() * 1000 + self.index()
59 }
60
61 pub fn id(self) -> String {
62 format!("E{:04}", self.numeric())
63 }
64
65 pub const fn exit_code(self) -> i32 {
66 match self.kind() {
67 ErrorKind::User => exit_status::USER,
69 ErrorKind::Config => exit_status::CONFIG,
71 ErrorKind::State => exit_status::STATE,
72 ErrorKind::Registry => exit_status::REGISTRY,
74 ErrorKind::Git => exit_status::GIT,
75 ErrorKind::Io => exit_status::IO,
76 ErrorKind::Process => exit_status::PROCESS,
77 ErrorKind::Validation => exit_status::VALIDATION,
79 ErrorKind::Release => exit_status::RELEASE,
80 ErrorKind::Hook => exit_status::HOOK,
81 ErrorKind::Ai => exit_status::AI,
82 ErrorKind::Runtime => exit_status::RUNTIME,
84 }
85 }
86 }
87
88 impl fmt::Display for ErrorCode {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(f, "{} ({})", self.message(), self.id())
91 }
92 }
93 };
94}
95
96error_codes! {
97 UserCancelled => (User, 1, "Operation cancelled"),
98 UserInteractionRequired => (User, 2, "Interactive input required"),
99 UserInvalidArgument => (User, 3, "Invalid argument"),
100 FormatUnsupported => (User, 4, "Format is not supported for this command"),
101 InvalidInput => (User, 5, "Input is invalid"),
102
103 ConfigInvalid => (Config, 1, "Configuration is invalid"),
104 ConfigUnreadable => (Config, 2, "Configuration is unreadable"),
105 ConfigReferenceInvalid => (Config, 3, "Configuration reference is invalid"),
106
107 StateInvalid => (State, 1, "State is invalid"),
108 StateUnreadable => (State, 2, "State is unreadable"),
109
110 RegistryUnknown => (Registry, 1, "Registry is unknown"),
111 RegistryInvalid => (Registry, 2, "Registry is invalid"),
112 RegistryUnreachable => (Registry, 3, "Registry is unreachable"),
113 RegistrySyncFailed => (Registry, 4, "Registry sync failed"),
114 RegistryRefNotFound => (Registry, 5, "Registry ref not found"),
115 RegistrySectionMissing => (Registry, 6, "Registry section is missing"),
116 RegistryOffline => (Registry, 7, "Registry unavailable in offline mode"),
117
118 GitMissing => (Git, 1, "git is missing"),
119 GitRepoNotFound => (Git, 2, "Git repository not found"),
120 GitCommandFailed => (Git, 3, "Git command failed"),
121 GitPushBlocked => (Git, 4, "Push blocked by policy"),
122
123 ValidationFailed => (Validation, 1, "Validation failed"),
124 CommitInvalid => (Validation, 2, "Commit is invalid"),
125 PrInvalid => (Validation, 3, "Pull request is invalid"),
126 BranchInvalid => (Validation, 4, "Branch is invalid"),
127
128 ReleaseInvalid => (Release, 1, "Release is invalid"),
129 ReleaseTagExists => (Release, 2, "Release tag already exists"),
130 ReleaseBranchExists => (Release, 3, "Release branch already exists"),
131
132 HookInstallFailed => (Hook, 1, "Hook installation failed"),
133 HookExecutionFailed => (Hook, 2, "Hook execution failed"),
134
135 AiUnsupported => (Ai, 1, "AI is not supported for this command"),
136 AiProviderFailed => (Ai, 2, "AI provider failed"),
137
138 IoFailure => (Io, 1, "I/O failure"),
139 SerializationFailure => (Io, 2, "Serialization failure"),
140 UiPromptFailed => (Io, 3, "Prompt failed"),
141 OutputRenderFailure => (Io, 4, "Output render failure"),
142
143 ProcessFailure => (Process, 1, "Process failure"),
144
145 RuntimeFailure => (Runtime, 1, "Runtime failure"),
146}