Skip to main content

a3s_code_core/code_intelligence/
error.rs

1use super::{CodePosition, LanguageId};
2use crate::workspace::WorkspacePath;
3use std::time::Duration;
4
5/// Result type for semantic code intelligence operations.
6pub type CodeIntelligenceResult<T> = std::result::Result<T, CodeIntelligenceError>;
7
8/// Typed failure returned by a code intelligence runtime.
9#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
10#[non_exhaustive]
11pub enum CodeIntelligenceError {
12    #[error("Code Intelligence is unavailable: {message}")]
13    Unavailable { message: String },
14
15    #[error("Code Intelligence operation '{operation}' is unsupported: {message}")]
16    Unsupported { operation: String, message: String },
17
18    #[error("workspace path {path:?} cannot be used for Code Intelligence: {message}")]
19    InvalidPath {
20        path: WorkspacePath,
21        message: String,
22    },
23
24    #[error("invalid position {position:?} for workspace document {path:?}")]
25    InvalidPosition {
26        path: WorkspacePath,
27        position: CodePosition,
28    },
29
30    #[error("Code Intelligence operation was cancelled")]
31    Cancelled,
32
33    #[error("Code Intelligence operation '{operation}' timed out after {duration:?}")]
34    Timeout {
35        operation: String,
36        duration: Duration,
37    },
38
39    #[error("Code Intelligence process for '{language}' exited: {message}")]
40    ProcessExited {
41        language: LanguageId,
42        message: String,
43    },
44
45    #[error("Code Intelligence protocol error: {message}")]
46    Protocol { message: String },
47}
48
49impl CodeIntelligenceError {
50    /// Stable machine-readable code for API and tool adapters.
51    pub const fn code(&self) -> &'static str {
52        match self {
53            Self::Unavailable { .. } => "CODE_INTELLIGENCE_UNAVAILABLE",
54            Self::Unsupported { .. } => "CODE_INTELLIGENCE_UNSUPPORTED",
55            Self::InvalidPath { .. } => "CODE_INTELLIGENCE_INVALID_PATH",
56            Self::InvalidPosition { .. } => "CODE_INTELLIGENCE_INVALID_POSITION",
57            Self::Cancelled => "CODE_INTELLIGENCE_CANCELLED",
58            Self::Timeout { .. } => "CODE_INTELLIGENCE_TIMEOUT",
59            Self::ProcessExited { .. } => "CODE_INTELLIGENCE_PROCESS_EXITED",
60            Self::Protocol { .. } => "CODE_INTELLIGENCE_PROTOCOL_ERROR",
61        }
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    fn assert_send_sync<T: Send + Sync>() {}
70
71    #[test]
72    fn errors_are_send_and_sync() {
73        assert_send_sync::<CodeIntelligenceError>();
74    }
75
76    #[test]
77    fn error_codes_are_stable_and_messages_keep_context() {
78        let error = CodeIntelligenceError::Timeout {
79            operation: "document_symbols".to_string(),
80            duration: Duration::from_secs(2),
81        };
82
83        assert_eq!(error.code(), "CODE_INTELLIGENCE_TIMEOUT");
84        assert!(error.to_string().contains("document_symbols"));
85        assert!(error.to_string().contains("2s"));
86    }
87}