1use chrono::{DateTime, Utc};
3use object_store::Error as ObjectStoreError;
4
5use crate::kernel::transaction::{CommitBuilderError, TransactionError};
6
7pub type DeltaResult<T, E = DeltaTableError> = Result<T, E>;
9
10#[allow(missing_docs)]
12#[derive(thiserror::Error, Debug)]
13pub enum DeltaTableError {
14 #[error("Kernel error: {0}")]
15 KernelError(#[from] delta_kernel::error::Error),
16
17 #[error("Failed to read delta log object: {}", .source)]
19 ObjectStore {
20 #[from]
22 source: ObjectStoreError,
23 },
24
25 #[error("Failed to parse parquet: {}", .source)]
27 Parquet {
28 #[from]
30 source: parquet::errors::ParquetError,
31 },
32
33 #[error("Failed to convert into Arrow schema: {}", .source)]
35 Arrow {
36 #[from]
38 source: arrow::error::ArrowError,
39 },
40
41 #[error("Invalid JSON in log record, version={}, line=`{}`, err=`{}`", .version, .line, .json_err)]
43 InvalidJsonLog {
44 json_err: serde_json::error::Error,
46 line: String,
48 version: i64,
50 },
51
52 #[error("Invalid JSON in file stats: {}", .json_err)]
54 InvalidStatsJson {
55 json_err: serde_json::error::Error,
57 },
58
59 #[error("Invalid table version: {0}")]
61 InvalidVersion(i64),
62
63 #[error("Invalid datetime string: {}", .source)]
65 InvalidDateTimeString {
66 #[from]
68 source: chrono::ParseError,
69 },
70
71 #[error("{message}")]
73 InvalidData {
74 message: String,
76 },
77
78 #[error("Not a Delta table: {0}")]
80 NotATable(String),
81
82 #[error("No schema found, please make sure table is loaded.")]
84 NoSchema,
85
86 #[error("Data does not match the schema or partitions of the table: {}", msg)]
89 SchemaMismatch {
90 msg: String,
92 },
93
94 #[error("This partition is not formatted with key=value: {}", .partition)]
96 PartitionError {
97 partition: String,
99 },
100
101 #[error("Invalid partition filter found: {}.", .partition_filter)]
103 InvalidPartitionFilter {
104 partition_filter: String,
106 },
107
108 #[error("Failed to read line from log record")]
110 Io {
111 #[from]
113 source: std::io::Error,
114 },
115
116 #[error("Commit actions are unsound: {source}")]
118 CommitValidation {
119 source: CommitBuilderError,
121 },
122
123 #[error("Transaction failed: {source}")]
125 Transaction {
126 source: TransactionError,
128 },
129
130 #[error("Delta transaction failed, version {0} already exists.")]
132 VersionAlreadyExists(i64),
133
134 #[error("Delta transaction failed, version {0} does not follow {1}")]
136 VersionMismatch(i64, i64),
137
138 #[error("Delta-rs must be build with feature '{feature}' to support loading from: {url}.")]
140 MissingFeature {
141 feature: &'static str,
143 url: String,
145 },
146
147 #[error("Cannot infer storage location from: {0}")]
149 InvalidTableLocation(String),
150
151 #[error("Log JSON serialization error: {json_err}")]
153 SerializeLogJson {
154 json_err: serde_json::error::Error,
156 },
157
158 #[error("Generic DeltaTable error: {0}")]
160 Generic(String),
161
162 #[error("Generic error: {source}")]
164 GenericError {
165 source: Box<dyn std::error::Error + Send + Sync + 'static>,
167 },
168
169 #[error("Kernel: {source}")]
170 Kernel {
171 #[from]
172 source: crate::kernel::Error,
173 },
174
175 #[error("Table metadata is invalid: {0}")]
176 MetadataError(String),
177
178 #[error("Table has not yet been initialized")]
179 NotInitialized,
180
181 #[error("Table has not yet been initialized with files, therefore {0} is not supported")]
182 NotInitializedWithFiles(String),
183
184 #[error("Change Data not enabled for version: {version}, Start: {start}, End: {end}")]
185 ChangeDataNotRecorded { version: i64, start: i64, end: i64 },
186
187 #[error("Reading a table version: {version} that does not have change data enabled")]
188 ChangeDataNotEnabled { version: i64 },
189
190 #[error("Invalid version. Start version {start} is greater than end version {end}")]
191 ChangeDataInvalidVersionRange { start: i64, end: i64 },
192
193 #[error("End timestamp {ending_timestamp} is greater than latest commit timestamp")]
194 ChangeDataTimestampGreaterThanCommit { ending_timestamp: DateTime<Utc> },
195
196 #[error("No starting version or timestamp provided for CDC")]
197 NoStartingVersionOrTimestamp,
198}
199
200impl From<object_store::path::Error> for DeltaTableError {
201 fn from(err: object_store::path::Error) -> Self {
202 Self::GenericError {
203 source: Box::new(err),
204 }
205 }
206}
207
208impl From<serde_json::Error> for DeltaTableError {
209 fn from(value: serde_json::Error) -> Self {
210 DeltaTableError::InvalidStatsJson { json_err: value }
211 }
212}
213
214impl DeltaTableError {
215 pub fn not_a_table(path: impl AsRef<str>) -> Self {
217 let msg = format!(
218 "No snapshot or version 0 found, perhaps {} is an empty dir?",
219 path.as_ref()
220 );
221 Self::NotATable(msg)
222 }
223
224 pub fn generic(msg: impl ToString) -> Self {
226 Self::Generic(msg.to_string())
227 }
228}