convex_typegen/
errors.rs

1use std::fmt;
2
3/// Errors that can occur during the type generation process.
4#[derive(Debug)]
5pub enum ConvexTypeGeneratorError
6{
7    /// The schema file could not be found at the specified path
8    MissingSchemaFile,
9
10    /// Failed to parse a source file
11    ParsingFailed
12    {
13        /// Path to the file that failed to parse
14        file: String,
15        /// Details about the parsing failure
16        details: String,
17    },
18
19    /// The schema file exists but is empty
20    EmptySchemaFile
21    {
22        /// Path to the empty schema file
23        file: String,
24    },
25
26    /// The provided path doesn't have a valid file name component
27    InvalidPath(String),
28
29    /// The file name contains invalid Unicode characters
30    InvalidUnicode(String),
31    /// Failed to serialize the AST to JSON
32    SerializationFailed(serde_json::Error),
33
34    /// An IO error occurred while reading or writing files
35    IOError
36    {
37        /// Path to the file where the error occurred
38        file: String,
39        /// The underlying IO error
40        error: std::io::Error,
41    },
42
43    /// The schema file has invalid structure or content
44    InvalidSchema
45    {
46        /// Context where the invalid schema was found
47        context: String,
48        /// Details about why the schema is invalid
49        details: String,
50    },
51
52    /// A circular reference was detected in type definitions
53    CircularReference
54    {
55        /// The path of types that form the circular reference
56        path: Vec<String>,
57    },
58
59    /// An invalid type name was encountered
60    InvalidType
61    {
62        /// The invalid type that was found
63        found: String,
64        /// List of valid type names
65        valid_types: Vec<String>,
66    },
67}
68
69impl fmt::Display for ConvexTypeGeneratorError
70{
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
72    {
73        match self {
74            Self::MissingSchemaFile => write!(f, "Schema file not found"),
75            Self::ParsingFailed { file, details } => {
76                write!(f, "Failed to parse file '{}': {}", file, details)
77            }
78            Self::EmptySchemaFile { file } => {
79                write!(f, "Schema file '{}' is empty", file)
80            }
81            Self::InvalidPath(path) => {
82                write!(f, "Invalid path: {}", path)
83            }
84            Self::InvalidUnicode(path) => {
85                write!(f, "Path contains invalid Unicode: {}", path)
86            }
87            Self::SerializationFailed(err) => {
88                write!(f, "Failed to serialize AST: {}", err)
89            }
90            Self::IOError { file, error } => {
91                write!(f, "IO error while reading '{}': {}", file, error)
92            }
93            Self::InvalidSchema { context, details } => {
94                write!(f, "Invalid schema at {}: {}", context, details)
95            }
96            Self::CircularReference { path } => {
97                write!(f, "Circular type reference detected: {}", path.join(" -> "))
98            }
99            Self::InvalidType { found, valid_types } => {
100                write!(f, "Invalid type '{}'. Valid types are: {}", found, valid_types.join(", "))
101            }
102        }
103    }
104}
105
106// Add this implementation to convert std::io::Error to ConvexTypeGeneratorError
107impl From<std::io::Error> for ConvexTypeGeneratorError
108{
109    fn from(error: std::io::Error) -> Self
110    {
111        ConvexTypeGeneratorError::IOError {
112            file: String::new(),
113            error,
114        }
115    }
116}
117
118// Implement std::error::Error for better error handling
119impl std::error::Error for ConvexTypeGeneratorError {}
120
121impl ConvexTypeGeneratorError
122{
123    /// Adds file context to an IO error
124    pub fn with_file_context(self, file: impl Into<String>) -> Self
125    {
126        match self {
127            Self::IOError { error, .. } => Self::IOError {
128                file: file.into(),
129                error,
130            },
131            other => other,
132        }
133    }
134}