1use std::fmt;
2
3use thiserror::Error;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum ErrorCode {
7 EmptyInput,
8 ConfigNotFound,
9 InvalidConfig,
10 InvalidConfigInput,
11 InvalidJson,
12 InvalidPathComponent,
13 InvalidProjectMetadata,
14 InvalidRemoteAgentConfig,
15 InvalidTaskUpdate,
16 MigrationFailed,
17 MigrationRequired,
18 InteractiveRequired,
19 NoProjectRoots,
20 NoProjectsDiscovered,
21 ProjectNotFound,
22 InvalidProjectSelection,
23 AiParseFailed,
24 DispatchNotFound,
25 DispatchWriteFailed,
26 RemoteAgentNotConfigured,
27 RemoteDispatchFailed,
28 TaskNotFound,
29 ProjectWriteFailed,
30 TaskWriteFailed,
31}
32
33#[derive(Debug, Error)]
34#[error("{message}")]
35pub struct TrackError {
36 pub code: ErrorCode,
37 message: String,
38}
39
40impl TrackError {
41 pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
42 Self {
43 code,
44 message: message.into(),
45 }
46 }
47
48 pub fn message(&self) -> &str {
49 &self.message
50 }
51}
52
53impl fmt::Display for ErrorCode {
54 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55 let code = match self {
56 ErrorCode::EmptyInput => "EMPTY_INPUT",
57 ErrorCode::ConfigNotFound => "CONFIG_NOT_FOUND",
58 ErrorCode::InvalidConfig => "INVALID_CONFIG",
59 ErrorCode::InvalidConfigInput => "INVALID_CONFIG_INPUT",
60 ErrorCode::InvalidJson => "INVALID_JSON",
61 ErrorCode::InvalidPathComponent => "INVALID_PATH_COMPONENT",
62 ErrorCode::InvalidProjectMetadata => "INVALID_PROJECT_METADATA",
63 ErrorCode::InvalidRemoteAgentConfig => "INVALID_REMOTE_AGENT_CONFIG",
64 ErrorCode::InvalidTaskUpdate => "INVALID_TASK_UPDATE",
65 ErrorCode::MigrationFailed => "MIGRATION_FAILED",
66 ErrorCode::MigrationRequired => "MIGRATION_REQUIRED",
67 ErrorCode::InteractiveRequired => "INTERACTIVE_REQUIRED",
68 ErrorCode::NoProjectRoots => "NO_PROJECT_ROOTS",
69 ErrorCode::NoProjectsDiscovered => "NO_PROJECTS_DISCOVERED",
70 ErrorCode::ProjectNotFound => "PROJECT_NOT_FOUND",
71 ErrorCode::InvalidProjectSelection => "INVALID_PROJECT_SELECTION",
72 ErrorCode::AiParseFailed => "AI_PARSE_FAILED",
73 ErrorCode::DispatchNotFound => "DISPATCH_NOT_FOUND",
74 ErrorCode::DispatchWriteFailed => "DISPATCH_WRITE_FAILED",
75 ErrorCode::RemoteAgentNotConfigured => "REMOTE_AGENT_NOT_CONFIGURED",
76 ErrorCode::RemoteDispatchFailed => "REMOTE_DISPATCH_FAILED",
77 ErrorCode::TaskNotFound => "TASK_NOT_FOUND",
78 ErrorCode::ProjectWriteFailed => "PROJECT_WRITE_FAILED",
79 ErrorCode::TaskWriteFailed => "TASK_WRITE_FAILED",
80 };
81
82 formatter.write_str(code)
83 }
84}