Skip to main content

avro_rs/
error.rs

1use crate::{schema::SchemaKind, types::ValueKind};
2use std::fmt;
3
4#[derive(thiserror::Error, Debug)]
5pub enum Error {
6    #[error("Bad Snappy CRC32; expected {expected:x} but got {actual:x}")]
7    SnappyCrc32 { expected: u32, actual: u32 },
8
9    #[error("Invalid u8 for bool: {0}")]
10    BoolValue(u8),
11
12    #[error("Not a fixed value, required for decimal with fixed schema: {0:?}")]
13    FixedValue(ValueKind),
14
15    #[error("Not a bytes value, required for decimal with bytes schema: {0:?}")]
16    BytesValue(ValueKind),
17
18    #[error("Not a string value, required for uuid: {0:?}")]
19    GetUuidFromStringValue(ValueKind),
20
21    #[error("Two schemas with the same fullname were given: {0:?}")]
22    NameCollision(String),
23
24    #[error("Not a fixed or bytes type, required for decimal schema, got: {0:?}")]
25    ResolveDecimalSchema(SchemaKind),
26
27    #[error("Invalid utf-8 string")]
28    ConvertToUtf8(#[source] std::string::FromUtf8Error),
29
30    /// Describes errors happened while validating Avro data.
31    #[error("Value does not match schema")]
32    Validation,
33
34    #[error("Unable to allocate {desired} bytes (maximum allowed: {maximum})")]
35    MemoryAllocation { desired: usize, maximum: usize },
36
37    /// Describe a specific error happening with decimal representation
38    #[error("Number of bytes requested for decimal sign extension {requested} is less than the number of bytes needed to decode {needed}")]
39    SignExtend { requested: usize, needed: usize },
40
41    #[error("Failed to read boolean bytes")]
42    ReadBoolean(#[source] std::io::Error),
43
44    #[error("Failed to read bytes")]
45    ReadBytes(#[source] std::io::Error),
46
47    #[error("Failed to read string")]
48    ReadString(#[source] std::io::Error),
49
50    #[error("Failed to read double")]
51    ReadDouble(#[source] std::io::Error),
52
53    #[error("Failed to read float")]
54    ReadFloat(#[source] std::io::Error),
55
56    #[error("Failed to read duration")]
57    ReadDuration(#[source] std::io::Error),
58
59    #[error("Failed to read fixed number of bytes: {1}")]
60    ReadFixed(#[source] std::io::Error, usize),
61
62    #[error("Failed to convert &str to UUID")]
63    ConvertStrToUuid(#[source] uuid::Error),
64
65    #[error("Map key is not a string; key type is {0:?}")]
66    MapKeyType(ValueKind),
67
68    #[error("Union index {index} out of bounds: {num_variants}")]
69    GetUnionVariant { index: i64, num_variants: usize },
70
71    #[error("Enum symbol index out of bounds: {num_variants}")]
72    EnumSymbolIndex { index: usize, num_variants: usize },
73
74    #[error("Enum symbol not found")]
75    GetEnumSymbol,
76
77    #[error("Scale {scale} is greater than precision {precision}")]
78    GetScaleAndPrecision { scale: usize, precision: usize },
79
80    #[error(
81        "Fixed type number of bytes {size} is not large enough to hold decimal values of precision {precision}"
82    )]
83    GetScaleWithFixedSize { size: usize, precision: usize },
84
85    #[error("expected UUID, got: {0:?}")]
86    GetUuid(ValueKind),
87
88    #[error("Fixed bytes of size 12 expected, got Fixed of size {0}")]
89    GetDecimalFixedBytes(usize),
90
91    #[error("Duration expected, got {0:?}")]
92    ResolveDuration(ValueKind),
93
94    #[error("Decimal expected, got {0:?}")]
95    ResolveDecimal(ValueKind),
96
97    #[error("Missing field in record: {0:?}")]
98    GetField(String),
99
100    #[error("Unable to convert to u8, got {0:?}")]
101    GetU8(ValueKind),
102
103    #[error("Precision {precision} too small to hold decimal values with {num_bytes} bytes")]
104    ComparePrecisionAndSize { precision: usize, num_bytes: usize },
105
106    #[error("Cannot convert length to i32: {1}")]
107    ConvertLengthToI32(#[source] std::num::TryFromIntError, usize),
108
109    #[error("Date expected, got {0:?}")]
110    GetDate(ValueKind),
111
112    #[error("TimeMillis expected, got {0:?}")]
113    GetTimeMillis(ValueKind),
114
115    #[error("TimeMicros expected, got {0:?}")]
116    GetTimeMicros(ValueKind),
117
118    #[error("TimestampMillis expected, got {0:?}")]
119    GetTimestampMillis(ValueKind),
120
121    #[error("TimestampMicros expected, got {0:?}")]
122    GetTimestampMicros(ValueKind),
123
124    #[error("Null expected, got {0:?}")]
125    GetNull(ValueKind),
126
127    #[error("Boolean expected, got {0:?}")]
128    GetBoolean(ValueKind),
129
130    #[error("Int expected, got {0:?}")]
131    GetInt(ValueKind),
132
133    #[error("Long expected, got {0:?}")]
134    GetLong(ValueKind),
135
136    #[error("Double expected, got {0:?}")]
137    GetDouble(ValueKind),
138
139    #[error("Float expected, got {0:?}")]
140    GetFloat(ValueKind),
141
142    #[error("Bytes expected, got {0:?}")]
143    GetBytes(ValueKind),
144
145    #[error("String expected, got {0:?}")]
146    GetString(ValueKind),
147
148    #[error("Enum expected, got {0:?}")]
149    GetEnum(ValueKind),
150
151    #[error("Fixed size mismatch, {size} expected, got {n}")]
152    CompareFixedSizes { size: usize, n: usize },
153
154    #[error("String expected for fixed, got {0:?}")]
155    GetStringForFixed(ValueKind),
156
157    #[error("Enum default {symbol:?} is not among allowed symbols {symbols:?}")]
158    GetEnumDefault {
159        symbol: String,
160        symbols: Vec<String>,
161    },
162
163    #[error("Enum value index {index} is out of bounds {nsymbols}")]
164    GetEnumValue { index: usize, nsymbols: usize },
165
166    #[error("Key {0} not found in decimal metadata JSON")]
167    GetDecimalMetadataFromJson(&'static str),
168
169    #[error("Could not find matching type in union")]
170    FindUnionVariant,
171
172    #[error("Array({expected:?}) expected, got {other:?}")]
173    GetArray {
174        expected: SchemaKind,
175        other: ValueKind,
176    },
177
178    #[error("Map({expected:?}) expected, got {other:?}")]
179    GetMap {
180        expected: SchemaKind,
181        other: ValueKind,
182    },
183
184    #[error("Record with fields {expected:?} expected, got {other:?}")]
185    GetRecord {
186        expected: Vec<(String, SchemaKind)>,
187        other: ValueKind,
188    },
189
190    #[error("No `name` field")]
191    GetNameField,
192
193    #[error("No `name` in record field")]
194    GetNameFieldFromRecord,
195
196    #[error("Unions may not directly contain a union")]
197    GetNestedUnion,
198
199    #[error("Unions cannot contain duplicate types")]
200    GetUnionDuplicate,
201
202    #[error("JSON value {0} claims to be u64 but cannot be converted")]
203    GetU64FromJson(serde_json::Number),
204
205    #[error("JSON value {0} claims to be i64 but cannot be converted")]
206    GetI64FromJson(serde_json::Number),
207
208    #[error("Cannot convert u64 to usize: {1}")]
209    ConvertU64ToUsize(#[source] std::num::TryFromIntError, u64),
210
211    #[error("Cannot convert i64 to usize: {1}")]
212    ConvertI64ToUsize(#[source] std::num::TryFromIntError, i64),
213
214    #[error("Cannot convert i32 to usize: {1}")]
215    ConvertI32ToUsize(#[source] std::num::TryFromIntError, i32),
216
217    #[error("Invalid JSON value for decimal precision/scale integer: {0}")]
218    GetPrecisionOrScaleFromJson(serde_json::Number),
219
220    #[error("Failed to parse schema from JSON")]
221    ParseSchemaJson(#[source] serde_json::Error),
222
223    #[error("Must be a JSON string, object or array")]
224    ParseSchemaFromValidJson,
225
226    #[error("Unknown primitiive type: {0}")]
227    ParsePrimitive(String),
228
229    #[error("invalid JSON for {key:?}: {precision:?}")]
230    GetDecimalPrecisionFromJson {
231        key: String,
232        precision: serde_json::Value,
233    },
234
235    #[error("Unexpected `type` {0} variant for `logicalType`")]
236    GetLogicalTypeVariant(serde_json::Value),
237
238    #[error("No `type` field found for `logicalType`")]
239    GetLogicalTypeField,
240
241    #[error("logicalType must be a string")]
242    GetLogicalTypeFieldType,
243
244    #[error("Unknown complex type: {0}")]
245    GetComplexType(serde_json::Value),
246
247    #[error("No `type` in complex type")]
248    GetComplexTypeField,
249
250    #[error("No `fields` in record")]
251    GetRecordFieldsJson,
252
253    #[error("No `symbols` field in enum")]
254    GetEnumSymbolsField,
255
256    #[error("Unable to parse `symbols` in enum")]
257    GetEnumSymbols,
258
259    #[error("No `items` in array")]
260    GetArrayItemsField,
261
262    #[error("No `values` in map")]
263    GetMapValuesField,
264
265    #[error("No `size` in fixed")]
266    GetFixedSizeField,
267
268    #[error("Failed to compress with flate")]
269    DeflateCompress(#[source] std::io::Error),
270
271    #[error("Failed to finish flate compressor")]
272    DeflateCompressFinish(std::io::Error),
273
274    #[error("Failed to decompress with flate")]
275    DeflateDecompress(#[source] std::io::Error),
276
277    #[cfg(feature = "snappy")]
278    #[error("Failed to compress with snappy")]
279    SnappyCompress(#[source] snap::Error),
280
281    #[cfg(feature = "snappy")]
282    #[error("Failed to get snappy decompression length")]
283    GetSnappyDecompressLen(#[source] snap::Error),
284
285    #[cfg(feature = "snappy")]
286    #[error("Failed to decompress with snappy")]
287    SnappyDecompress(#[source] snap::Error),
288
289    #[error("Failed to read header")]
290    ReadHeader(#[source] std::io::Error),
291
292    #[error("wrong magic in header")]
293    HeaderMagic,
294
295    #[error("Failed to get JSON from avro.schema key in map")]
296    GetAvroSchemaFromMap,
297
298    #[error("no metadata in header")]
299    GetHeaderMetadata,
300
301    #[error("Failed to read marker bytes")]
302    ReadMarker(#[source] std::io::Error),
303
304    #[error("Failed to read block marker bytes")]
305    ReadBlockMarker(#[source] std::io::Error),
306
307    #[error("Read into buffer failed")]
308    ReadIntoBuf(#[source] std::io::Error),
309
310    #[error("block marker does not match header marker")]
311    GetBlockMarker,
312
313    #[error("Overflow when decoding integer value")]
314    IntegerOverflow,
315
316    #[error("Failed to read bytes for decoding variable length integer")]
317    ReadVariableIntegerBytes(#[source] std::io::Error),
318
319    #[error("Decoded integer out of range for i32: {1}")]
320    ZagI32(#[source] std::num::TryFromIntError, i64),
321
322    #[error("unable to read block")]
323    ReadBlock,
324
325    #[error("Failed to serialize value into Avro value: {0}")]
326    SerializeValue(String),
327
328    #[error("Failed to deserialize Avro value into value: {0}")]
329    DeserializeValue(String),
330
331    #[error("Failed to write buffer bytes during flush")]
332    WriteBytes(#[source] std::io::Error),
333
334    #[error("Failed to write marker")]
335    WriteMarker(#[source] std::io::Error),
336
337    #[error("Failed to convert JSON to string")]
338    ConvertJsonToString(#[source] serde_json::Error),
339
340    /// Error while converting float to json value
341    #[error("failed to convert avro float to json: {0}")]
342    ConvertF64ToJson(f64),
343}
344
345impl serde::ser::Error for Error {
346    fn custom<T: fmt::Display>(msg: T) -> Self {
347        Error::SerializeValue(msg.to_string())
348    }
349}
350
351impl serde::de::Error for Error {
352    fn custom<T: fmt::Display>(msg: T) -> Self {
353        Error::DeserializeValue(msg.to_string())
354    }
355}