1use crate::{
19 schema::{Name, Schema, SchemaKind},
20 types::{Value, ValueKind},
21};
22use std::{error::Error as _, fmt};
23
24#[derive(thiserror::Error)]
25pub enum Error {
26 #[error("Bad Snappy CRC32; expected {expected:x} but got {actual:x}")]
27 SnappyCrc32 { expected: u32, actual: u32 },
28
29 #[error("Invalid u8 for bool: {0}")]
30 BoolValue(u8),
31
32 #[error("Not a fixed value, required for decimal with fixed schema: {0:?}")]
33 FixedValue(ValueKind),
34
35 #[error("Not a bytes value, required for decimal with bytes schema: {0:?}")]
36 BytesValue(ValueKind),
37
38 #[error("Not a string value, required for uuid: {0:?}")]
39 GetUuidFromStringValue(ValueKind),
40
41 #[error("Two schemas with the same fullname were given: {0:?}")]
42 NameCollision(String),
43
44 #[error("Not a fixed or bytes type, required for decimal schema, got: {0:?}")]
45 ResolveDecimalSchema(SchemaKind),
46
47 #[error("Invalid utf-8 string")]
48 ConvertToUtf8(#[source] std::string::FromUtf8Error),
49
50 #[error("Invalid utf-8 string")]
51 ConvertToUtf8Error(#[source] std::str::Utf8Error),
52
53 #[error("Value does not match schema")]
55 Validation,
56
57 #[error("Value {value:?} does not match schema {schema:?}: Reason: {reason}")]
59 ValidationWithReason {
60 value: Value,
61 schema: Schema,
62 reason: String,
63 },
64
65 #[error("Unable to allocate {desired} bytes (maximum allowed: {maximum})")]
66 MemoryAllocation { desired: usize, maximum: usize },
67
68 #[error("Number of bytes requested for decimal sign extension {requested} is less than the number of bytes needed to decode {needed}")]
70 SignExtend { requested: usize, needed: usize },
71
72 #[error("Failed to read boolean bytes")]
73 ReadBoolean(#[source] std::io::Error),
74
75 #[error("Failed to read bytes")]
76 ReadBytes(#[source] std::io::Error),
77
78 #[error("Failed to read string")]
79 ReadString(#[source] std::io::Error),
80
81 #[error("Failed to read double")]
82 ReadDouble(#[source] std::io::Error),
83
84 #[error("Failed to read float")]
85 ReadFloat(#[source] std::io::Error),
86
87 #[error("Failed to read duration")]
88 ReadDuration(#[source] std::io::Error),
89
90 #[error("Failed to read fixed number of bytes: {1}")]
91 ReadFixed(#[source] std::io::Error, usize),
92
93 #[error("Failed to convert &str to UUID")]
94 ConvertStrToUuid(#[source] uuid::Error),
95
96 #[error("Failed to convert Fixed bytes to UUID. It must be exactly 16 bytes, got {0}")]
97 ConvertFixedToUuid(usize),
98
99 #[error("Failed to convert Fixed bytes to UUID")]
100 ConvertSliceToUuid(#[source] uuid::Error),
101
102 #[error("Map key is not a string; key type is {0:?}")]
103 MapKeyType(ValueKind),
104
105 #[error("Union index {index} out of bounds: {num_variants}")]
106 GetUnionVariant { index: i64, num_variants: usize },
107
108 #[error("Enum symbol index out of bounds: {num_variants}")]
109 EnumSymbolIndex { index: usize, num_variants: usize },
110
111 #[error("Enum symbol not found {0}")]
112 GetEnumSymbol(String),
113
114 #[error("Unable to decode enum index")]
115 GetEnumUnknownIndexValue,
116
117 #[error("Scale {scale} is greater than precision {precision}")]
118 GetScaleAndPrecision { scale: usize, precision: usize },
119
120 #[error(
121 "Fixed type number of bytes {size} is not large enough to hold decimal values of precision {precision}"
122 )]
123 GetScaleWithFixedSize { size: usize, precision: usize },
124
125 #[error("expected UUID, got: {0:?}")]
126 GetUuid(ValueKind),
127
128 #[error("expected BigDecimal, got: {0:?}")]
129 GetBigdecimal(ValueKind),
130
131 #[error("Fixed bytes of size 12 expected, got Fixed of size {0}")]
132 GetDecimalFixedBytes(usize),
133
134 #[error("Duration expected, got {0:?}")]
135 ResolveDuration(ValueKind),
136
137 #[error("Decimal expected, got {0:?}")]
138 ResolveDecimal(ValueKind),
139
140 #[error("Missing field in record: {0:?}")]
141 GetField(String),
142
143 #[error("Unable to convert to u8, got {0:?}")]
144 GetU8(ValueKind),
145
146 #[error("Precision {precision} too small to hold decimal values with {num_bytes} bytes")]
147 ComparePrecisionAndSize { precision: usize, num_bytes: usize },
148
149 #[error("Cannot convert length to i32: {1}")]
150 ConvertLengthToI32(#[source] std::num::TryFromIntError, usize),
151
152 #[error("Date expected, got {0:?}")]
153 GetDate(ValueKind),
154
155 #[error("TimeMillis expected, got {0:?}")]
156 GetTimeMillis(ValueKind),
157
158 #[error("TimeMicros expected, got {0:?}")]
159 GetTimeMicros(ValueKind),
160
161 #[error("TimestampMillis expected, got {0:?}")]
162 GetTimestampMillis(ValueKind),
163
164 #[error("TimestampMicros expected, got {0:?}")]
165 GetTimestampMicros(ValueKind),
166
167 #[error("TimestampNanos expected, got {0:?}")]
168 GetTimestampNanos(ValueKind),
169
170 #[error("LocalTimestampMillis expected, got {0:?}")]
171 GetLocalTimestampMillis(ValueKind),
172
173 #[error("LocalTimestampMicros expected, got {0:?}")]
174 GetLocalTimestampMicros(ValueKind),
175
176 #[error("LocalTimestampNanos expected, got {0:?}")]
177 GetLocalTimestampNanos(ValueKind),
178
179 #[error("Null expected, got {0:?}")]
180 GetNull(ValueKind),
181
182 #[error("Boolean expected, got {0:?}")]
183 GetBoolean(ValueKind),
184
185 #[error("Int expected, got {0:?}")]
186 GetInt(ValueKind),
187
188 #[error("Long expected, got {0:?}")]
189 GetLong(ValueKind),
190
191 #[error("Double expected, got {0:?}")]
192 GetDouble(ValueKind),
193
194 #[error("Float expected, got {0:?}")]
195 GetFloat(ValueKind),
196
197 #[error("Bytes expected, got {0:?}")]
198 GetBytes(ValueKind),
199
200 #[error("String expected, got {0:?}")]
201 GetString(ValueKind),
202
203 #[error("Enum expected, got {0:?}")]
204 GetEnum(ValueKind),
205
206 #[error("Fixed size mismatch, {size} expected, got {n}")]
207 CompareFixedSizes { size: usize, n: usize },
208
209 #[error("String expected for fixed, got {0:?}")]
210 GetStringForFixed(ValueKind),
211
212 #[error("Enum default {symbol:?} is not among allowed symbols {symbols:?}")]
213 GetEnumDefault {
214 symbol: String,
215 symbols: Vec<String>,
216 },
217
218 #[error("Enum value index {index} is out of bounds {nsymbols}")]
219 GetEnumValue { index: usize, nsymbols: usize },
220
221 #[error("Key {0} not found in decimal metadata JSON")]
222 GetDecimalMetadataFromJson(&'static str),
223
224 #[error("Could not find matching type in union")]
225 FindUnionVariant,
226
227 #[error("Union type should not be empty")]
228 EmptyUnion,
229
230 #[error("Array({expected:?}) expected, got {other:?}")]
231 GetArray {
232 expected: SchemaKind,
233 other: ValueKind,
234 },
235
236 #[error("Map({expected:?}) expected, got {other:?}")]
237 GetMap {
238 expected: SchemaKind,
239 other: ValueKind,
240 },
241
242 #[error("Record with fields {expected:?} expected, got {other:?}")]
243 GetRecord {
244 expected: Vec<(String, SchemaKind)>,
245 other: ValueKind,
246 },
247
248 #[error("No `name` field")]
249 GetNameField,
250
251 #[error("No `name` in record field")]
252 GetNameFieldFromRecord,
253
254 #[error("Unions may not directly contain a union")]
255 GetNestedUnion,
256
257 #[error("Unions cannot contain duplicate types")]
258 GetUnionDuplicate,
259
260 #[error("One union type {0:?} must match the `default`'s value type {1:?}")]
261 GetDefaultUnion(SchemaKind, ValueKind),
262
263 #[error("`default`'s value type of field {0:?} in {1:?} must be {2:?}")]
264 GetDefaultRecordField(String, String, String),
265
266 #[error("JSON value {0} claims to be u64 but cannot be converted")]
267 GetU64FromJson(serde_json::Number),
268
269 #[error("JSON value {0} claims to be i64 but cannot be converted")]
270 GetI64FromJson(serde_json::Number),
271
272 #[error("Cannot convert u64 to usize: {1}")]
273 ConvertU64ToUsize(#[source] std::num::TryFromIntError, u64),
274
275 #[error("Cannot convert u32 to usize: {1}")]
276 ConvertU32ToUsize(#[source] std::num::TryFromIntError, u32),
277
278 #[error("Cannot convert i64 to usize: {1}")]
279 ConvertI64ToUsize(#[source] std::num::TryFromIntError, i64),
280
281 #[error("Cannot convert i32 to usize: {1}")]
282 ConvertI32ToUsize(#[source] std::num::TryFromIntError, i32),
283
284 #[error("Invalid JSON value for decimal precision/scale integer: {0}")]
285 GetPrecisionOrScaleFromJson(serde_json::Number),
286
287 #[error("Failed to parse schema from JSON")]
288 ParseSchemaJson(#[source] serde_json::Error),
289
290 #[error("Failed to read schema")]
291 ReadSchemaFromReader(#[source] std::io::Error),
292
293 #[error("Must be a JSON string, object or array")]
294 ParseSchemaFromValidJson,
295
296 #[error("Unknown primitive type: {0}")]
297 ParsePrimitive(String),
298
299 #[error("invalid JSON for {key:?}: {value:?}")]
300 GetDecimalMetadataValueFromJson {
301 key: String,
302 value: serde_json::Value,
303 },
304
305 #[error("The decimal precision ({precision}) must be bigger or equal to the scale ({scale})")]
306 DecimalPrecisionLessThanScale { precision: usize, scale: usize },
307
308 #[error("The decimal precision ({precision}) must be a positive number")]
309 DecimalPrecisionMuBePositive { precision: usize },
310
311 #[error("Unreadable big decimal sign")]
312 BigDecimalSign,
313
314 #[error("Unreadable length for big decimal inner bytes: {0}")]
315 BigDecimalLen(#[source] Box<Error>),
316
317 #[error("Unreadable big decimal scale")]
318 BigDecimalScale,
319
320 #[error("Unexpected `type` {0} variant for `logicalType`")]
321 GetLogicalTypeVariant(serde_json::Value),
322
323 #[error("No `type` field found for `logicalType`")]
324 GetLogicalTypeField,
325
326 #[error("logicalType must be a string, but is {0:?}")]
327 GetLogicalTypeFieldType(serde_json::Value),
328
329 #[error("Unknown complex type: {0}")]
330 GetComplexType(serde_json::Value),
331
332 #[error("No `type` in complex type")]
333 GetComplexTypeField,
334
335 #[error("No `fields` in record")]
336 GetRecordFieldsJson,
337
338 #[error("No `symbols` field in enum")]
339 GetEnumSymbolsField,
340
341 #[error("Unable to parse `symbols` in enum")]
342 GetEnumSymbols,
343
344 #[error("Invalid enum symbol name {0}")]
345 EnumSymbolName(String),
346
347 #[error("Invalid field name {0}")]
348 FieldName(String),
349
350 #[error("Duplicate field name {0}")]
351 FieldNameDuplicate(String),
352
353 #[error("Invalid schema name {0}. It must match the regex '{1}'")]
354 InvalidSchemaName(String, &'static str),
355
356 #[error("Invalid namespace {0}. It must match the regex '{1}'")]
357 InvalidNamespace(String, &'static str),
358
359 #[error("Duplicate enum symbol {0}")]
360 EnumSymbolDuplicate(String),
361
362 #[error("Default value for enum must be a string! Got: {0}")]
363 EnumDefaultWrongType(serde_json::Value),
364
365 #[error("No `items` in array")]
366 GetArrayItemsField,
367
368 #[error("No `values` in map")]
369 GetMapValuesField,
370
371 #[error("Fixed schema `size` value must be a positive integer: {0}")]
372 GetFixedSizeFieldPositive(serde_json::Value),
373
374 #[error("Fixed schema has no `size`")]
375 GetFixedSizeField,
376
377 #[error("Fixed schema's default value length ({0}) does not match its size ({1})")]
378 FixedDefaultLenSizeMismatch(usize, u64),
379
380 #[error("Failed to compress with flate")]
381 DeflateCompress(#[source] std::io::Error),
382
383 #[error("Failed to finish flate compressor")]
384 DeflateCompressFinish(#[source] std::io::Error),
385
386 #[error("Failed to decompress with flate")]
387 DeflateDecompress(#[source] std::io::Error),
388
389 #[cfg(feature = "snappy")]
390 #[error("Failed to compress with snappy")]
391 SnappyCompress(#[source] snap::Error),
392
393 #[cfg(feature = "snappy")]
394 #[error("Failed to get snappy decompression length")]
395 GetSnappyDecompressLen(#[source] snap::Error),
396
397 #[cfg(feature = "snappy")]
398 #[error("Failed to decompress with snappy")]
399 SnappyDecompress(#[source] snap::Error),
400
401 #[error("Failed to compress with zstd")]
402 ZstdCompress(#[source] std::io::Error),
403
404 #[error("Failed to decompress with zstd")]
405 ZstdDecompress(#[source] std::io::Error),
406
407 #[error("Failed to read header")]
408 ReadHeader(#[source] std::io::Error),
409
410 #[error("wrong magic in header")]
411 HeaderMagic,
412
413 #[error("Message Header mismatch. Expected: {0:?}. Actual: {1:?}")]
414 SingleObjectHeaderMismatch([u8; 10], [u8; 10]),
415
416 #[error("Failed to get JSON from avro.schema key in map")]
417 GetAvroSchemaFromMap,
418
419 #[error("no metadata in header")]
420 GetHeaderMetadata,
421
422 #[error("Failed to read marker bytes")]
423 ReadMarker(#[source] std::io::Error),
424
425 #[error("Failed to read block marker bytes")]
426 ReadBlockMarker(#[source] std::io::Error),
427
428 #[error("Read into buffer failed")]
429 ReadIntoBuf(#[source] std::io::Error),
430
431 #[error("block marker does not match header marker")]
432 GetBlockMarker,
433
434 #[error("Overflow when decoding integer value")]
435 IntegerOverflow,
436
437 #[error("Failed to read bytes for decoding variable length integer")]
438 ReadVariableIntegerBytes(#[source] std::io::Error),
439
440 #[error("Decoded integer out of range for i32: {1}")]
441 ZagI32(#[source] std::num::TryFromIntError, i64),
442
443 #[error("unable to read block")]
444 ReadBlock,
445
446 #[error("Failed to serialize value into Avro value: {0}")]
447 SerializeValue(String),
448
449 #[error("Failed to deserialize Avro value into value: {0}")]
450 DeserializeValue(String),
451
452 #[error("Failed to write buffer bytes during flush")]
453 WriteBytes(#[source] std::io::Error),
454
455 #[error("Failed to write marker")]
456 WriteMarker(#[source] std::io::Error),
457
458 #[error("Failed to convert JSON to string")]
459 ConvertJsonToString(#[source] serde_json::Error),
460
461 #[error("failed to convert avro float to json: {0}")]
463 ConvertF64ToJson(f64),
464
465 #[error("Unresolved schema reference: {0}")]
467 SchemaResolutionError(Name),
468
469 #[error("The file metadata is already flushed.")]
470 FileHeaderAlreadyWritten,
471
472 #[error("Metadata keys starting with 'avro.' are reserved for internal usage: {0}.")]
473 InvalidMetadataKey(String),
474
475 #[error("Two named schema defined for same fullname: {0}.")]
477 AmbiguousSchemaDefinition(Name),
478
479 #[error("Signed decimal bytes length {0} not equal to fixed schema size {1}.")]
480 EncodeDecimalAsFixedError(usize, usize),
481
482 #[error("There is no entry for '{0}' in the lookup table: {1}.")]
483 NoEntryInLookupTable(String, String),
484
485 #[error("Can only encode value type {value_kind:?} as one of {supported_schema:?}")]
486 EncodeValueAsSchemaError {
487 value_kind: ValueKind,
488 supported_schema: Vec<SchemaKind>,
489 },
490 #[error(
491 "Internal buffer not drained properly. Re-initialize the single object writer struct!"
492 )]
493 IllegalSingleObjectWriterState,
494
495 #[error("Codec '{0}' is not supported/enabled")]
496 CodecNotSupported(String),
497
498 #[error("Invalid Avro data! Cannot read codec type from value that is not Value::Bytes.")]
499 BadCodecMetadata,
500}
501
502#[derive(thiserror::Error, PartialEq)]
503pub enum CompatibilityError {
504 #[error("Incompatible schema types! Writer schema is '{writer_schema_type}', but reader schema is '{reader_schema_type}'")]
505 WrongType {
506 writer_schema_type: String,
507 reader_schema_type: String,
508 },
509
510 #[error("Incompatible schema types! The {schema_type} should have been {expected_type:?}")]
511 TypeExpected {
512 schema_type: String,
513 expected_type: Vec<SchemaKind>,
514 },
515
516 #[error("Incompatible schemata! Field '{0}' in reader schema does not match the type in the writer schema")]
517 FieldTypeMismatch(String, #[source] Box<CompatibilityError>),
518
519 #[error("Incompatible schemata! Field '{0}' in reader schema must have a default value")]
520 MissingDefaultValue(String),
521
522 #[error("Incompatible schemata! Reader's symbols must contain all writer's symbols")]
523 MissingSymbols,
524
525 #[error("Incompatible schemata! All elements in union must match for both schemas")]
526 MissingUnionElements,
527
528 #[error("Incompatible schemata! Name and size don't match for fixed")]
529 FixedMismatch,
530
531 #[error("Incompatible schemata! The name must be the same for both schemas. Writer's name {writer_name} and reader's name {reader_name}")]
532 NameMismatch {
533 writer_name: String,
534 reader_name: String,
535 },
536
537 #[error(
538 "Incompatible schemata! Unknown type for '{0}'. Make sure that the type is a valid one"
539 )]
540 Inconclusive(String),
541}
542
543impl serde::ser::Error for Error {
544 fn custom<T: fmt::Display>(msg: T) -> Self {
545 Error::SerializeValue(msg.to_string())
546 }
547}
548
549impl serde::de::Error for Error {
550 fn custom<T: fmt::Display>(msg: T) -> Self {
551 Error::DeserializeValue(msg.to_string())
552 }
553}
554
555impl fmt::Debug for Error {
556 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
557 let mut msg = self.to_string();
558 if let Some(e) = self.source() {
559 msg.extend([": ", &e.to_string()]);
560 }
561 write!(f, "{}", msg)
562 }
563}
564
565impl fmt::Debug for CompatibilityError {
566 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
567 let mut msg = self.to_string();
568 if let Some(e) = self.source() {
569 msg.extend([": ", &e.to_string()]);
570 }
571 write!(f, "{}", msg)
572 }
573}