Skip to content

Commit f89c6b5

Browse files
robert3005claude
andcommitted
Remove error kinds from VortexError
A VortexError is now a message, an optional source and a backtrace. The VortexErrorKind classification is gone, and with it kind(), the kind prefix in the displayed message and the classification of foreign errors in the From impls, which now keep the foreign error as the source. The error macros take a plain format string again. The Context: and External: forms remain, since they are not kinds. Every call site drops its kind tag, and vortex_ensure_eq! loses its kind-only form. Tests that asserted on a kind now assert on the guard's message. The Python bindings raise RuntimeError for every Vortex error, as before kinds existed. The C API keeps VX_ERROR_CODE_OTHER for Vortex errors and VX_ERROR_CODE_PANIC for panics, at their existing values, and the C++ ErrorCode mirrors it. Signed-off-by: Robert Kruszewski <github@robertk.io> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S7EtMqoZ91rrCCh9vS2yTm
1 parent d674c3b commit f89c6b5

770 files changed

Lines changed: 4658 additions & 5201 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎STYLE.md‎

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,9 @@
5454
- `vortex_panic!` for handling invariant violations
5555
- `vortex_ensure!` and `vortex_ensure_eq!` for checking conditions. Prefer
5656
`vortex_ensure_eq!(a, b)` with no message: the error already shows both expressions and values.
57-
Add a message only for context the expressions lack, and never repeat the values in it. With no
58-
message the error is `AssertionFailed`; when the check is on the caller's input rather than an
59-
internal invariant, name the kind alone, as in `vortex_ensure_eq!(a, b, InvalidArgument)`.
60-
- Every message names its `VortexErrorKind`, as in `vortex_bail!(InvalidArgument: "...")`; the
61-
macros reject a message without one. Choose the kind by what went wrong, the way Python picks an
62-
exception class: `InvalidArgument` (`ValueError`) for a value the callee rejects,
63-
`MismatchedTypes` (`TypeError`) for the wrong dtype, `OutOfBounds` (`IndexError`) for a position
64-
past the end, `NotFound` (`KeyError`) for a name that resolves to nothing, `Overflow`
65-
(`OverflowError`) for a value that does not fit its target, `NotImplemented`, `Serde` for an
66-
unreadable wire or file format, `Io` for a failed system or driver call, `AssertionFailed` for a
67-
broken internal invariant, and `Other` only when nothing else fits. Never classify by where the
68-
failure happened.
69-
- Add context to an existing error with `.with_context()`, which keeps its kind; do not format it
70-
into a new `vortex_err!`, which discards the kind.
57+
Add a message only for context the expressions lack, and never repeat the values in it.
58+
- Add context to an existing error with `.with_context()`, which keeps its source and backtrace;
59+
do not format it into a new `vortex_err!`, which discards them.
7160
- Include backtraces for better debugging
7261
- Use `VortexExpect` trait when unwrapping is appropriate with proper error context.
7362

‎encodings/alp/src/alp/array.rs‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl VTable for ALP {
9898
}
9999

100100
fn buffer(_array: ArrayView<'_, Self>, idx: usize) -> BufferHandle {
101-
vortex_panic!(OutOfBounds: "ALPArray buffer index {idx} out of bounds")
101+
vortex_panic!("ALPArray buffer index {idx} out of bounds")
102102
}
103103

104104
fn buffer_name(_array: ArrayView<'_, Self>, _idx: usize) -> Option<String> {
@@ -144,7 +144,7 @@ impl VTable for ALP {
144144
let encoded_ptype = match &dtype {
145145
DType::Primitive(PType::F32, n) => DType::Primitive(PType::I32, *n),
146146
DType::Primitive(PType::F64, n) => DType::Primitive(PType::I64, *n),
147-
d => vortex_bail!(MismatchedTypes: "expected type: f32 or f64 but instead got {}", d),
147+
d => vortex_bail!("expected type: f32 or f64 but instead got {}", d),
148148
};
149149
let encoded = children.get(0, &encoded_ptype, len)?;
150150

@@ -275,7 +275,7 @@ impl ALPData {
275275
encoded.dtype(),
276276
DType::Primitive(PType::I32 | PType::I64, _)
277277
),
278-
MismatchedTypes: "ALP encoded ints have invalid DType {}",
278+
"ALP encoded ints have invalid DType {}",
279279
encoded.dtype(),
280280
);
281281

@@ -284,15 +284,15 @@ impl ALPData {
284284
let Exponents { e, f } = exponents;
285285
match encoded.dtype().as_ptype() {
286286
PType::I32 => {
287-
vortex_ensure!(exponents.e <= f32::MAX_EXPONENT, InvalidArgument: "e out of bounds: {e}");
288-
vortex_ensure!(exponents.f <= f32::MAX_EXPONENT, InvalidArgument: "f out of bounds: {f}");
287+
vortex_ensure!(exponents.e <= f32::MAX_EXPONENT, "e out of bounds: {e}");
288+
vortex_ensure!(exponents.f <= f32::MAX_EXPONENT, "f out of bounds: {f}");
289289
if let Some(patches) = patches {
290290
Self::validate_patches::<f32>(patches, encoded)?;
291291
}
292292
}
293293
PType::I64 => {
294-
vortex_ensure!(e <= f64::MAX_EXPONENT, InvalidArgument: "e out of bounds: {e}");
295-
vortex_ensure!(f <= f64::MAX_EXPONENT, InvalidArgument: "f out of bounds: {f}");
294+
vortex_ensure!(e <= f64::MAX_EXPONENT, "e out of bounds: {e}");
295+
vortex_ensure!(f <= f64::MAX_EXPONENT, "f out of bounds: {f}");
296296

297297
if let Some(patches) = patches {
298298
Self::validate_patches::<f64>(patches, encoded)?;
@@ -303,7 +303,7 @@ impl ALPData {
303303

304304
// Validate patches
305305
if let Some(patches) = patches {
306-
vortex_ensure_eq!(patches.array_len(), encoded.len(), InvalidArgument);
306+
vortex_ensure_eq!(patches.array_len(), encoded.len());
307307

308308
// Verify that the patches DType are of the proper DType.
309309
}
@@ -320,7 +320,7 @@ impl ALPData {
320320
Ok(DType::Primitive(PType::F64, *nullability))
321321
}
322322
_ => {
323-
vortex_bail!(MismatchedTypes: "ALP encoded ints have invalid DType {}", encoded.dtype(),)
323+
vortex_bail!("ALP encoded ints have invalid DType {}", encoded.dtype(),)
324324
}
325325
}
326326
}
@@ -330,10 +330,10 @@ impl ALPData {
330330
patches: &Patches,
331331
encoded: &ArrayRef,
332332
) -> VortexResult<()> {
333-
vortex_ensure_eq!(patches.array_len(), encoded.len(), InvalidArgument);
333+
vortex_ensure_eq!(patches.array_len(), encoded.len());
334334

335335
let expected_type = DType::Primitive(T::PTYPE, encoded.dtype().nullability());
336-
vortex_ensure_eq!(patches.dtype(), &expected_type, MismatchedTypes);
336+
vortex_ensure_eq!(patches.dtype(), &expected_type);
337337

338338
Ok(())
339339
}
@@ -447,11 +447,11 @@ fn validate_parts(
447447
) -> VortexResult<()> {
448448
let logical_dtype = ALPData::logical_dtype(encoded)?;
449449
ALPData::validate_components(encoded, exponents, patches.as_ref())?;
450-
vortex_ensure_eq!(encoded.len(), len, InvalidArgument: "ALP encoded len must match outer len");
450+
vortex_ensure_eq!(encoded.len(), len, "ALP encoded len must match outer len");
451451
vortex_ensure_eq!(
452452
&logical_dtype,
453453
dtype,
454-
MismatchedTypes: "ALP dtype does not match encoded logical dtype"
454+
"ALP dtype does not match encoded logical dtype"
455455
);
456456
Ok(())
457457
}

‎encodings/alp/src/alp/compress.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ macro_rules! match_each_alp_float_ptype {
3939
type $enc = f64;
4040
$body
4141
}
42-
_ => vortex_panic!(MismatchedTypes: "ALP can only encode f32 and f64, got {}", ptype),
42+
_ => vortex_panic!("ALP can only encode f32 and f64, got {}", ptype),
4343
}
4444
}};
4545
}
@@ -52,7 +52,7 @@ pub fn alp_encode(
5252
let (exponents, encoded, patches) = match parray.ptype() {
5353
PType::F32 => alp_encode_components_typed::<f32>(parray, exponents, ctx)?,
5454
PType::F64 => alp_encode_components_typed::<f64>(parray, exponents, ctx)?,
55-
_ => vortex_bail!(MismatchedTypes: "ALP can only encode f32 and f64"),
55+
_ => vortex_bail!("ALP can only encode f32 and f64"),
5656
};
5757

5858
// SAFETY: alp_encode_components_typed must return well-formed components

‎encodings/alp/src/alp/compute/compare.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl CompareKernel for ALP {
4545
if let Some(const_scalar) = rhs.as_constant() {
4646
let pscalar = const_scalar.as_primitive_opt().ok_or_else(|| {
4747
vortex_err!(
48-
InvalidArgument: "ALP Compare RHS had the wrong type {}, expected {}",
48+
"ALP Compare RHS had the wrong type {}, expected {}",
4949
const_scalar,
5050
const_scalar.dtype()
5151
)
@@ -55,7 +55,7 @@ impl CompareKernel for ALP {
5555
match pscalar.typed_value::<T>() {
5656
Some(value) => return alp_scalar_compare(lhs, value, operator),
5757
None => vortex_bail!(
58-
InvalidArgument: "Failed to convert scalar {:?} to ALP type {:?}",
58+
"Failed to convert scalar {:?} to ALP type {:?}",
5959
pscalar,
6060
pscalar.ptype()
6161
),

‎encodings/alp/src/alp/ops.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl OperationsVTable<ALP> for ALP {
3636

3737
let encoded_val = state
3838
.slot(ALPSlots::ENCODED)?
39-
.ok_or_else(|| vortex_err!(InvalidArgument: "ALP encoded slot is missing"))?
39+
.ok_or_else(|| vortex_err!("ALP encoded slot is missing"))?
4040
.execute_scalar(index, ctx)?;
4141

4242
Ok(match_each_alp_float_ptype!(array.dtype().as_ptype(), |T| {

‎encodings/alp/src/alp/plugin.rs‎

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl ArrayPlugin for ALPPatchedPlugin {
5555
vortex_ensure_eq!(
5656
parts.serialized_id,
5757
self.id(),
58-
Serde: "ALP plugin does not recognize serialized ID"
58+
"ALP plugin does not recognize serialized ID"
5959
);
6060
let alp_array = Array::<ALP>::try_from_parts(ArrayVTable::deserialize(
6161
&ALP,
@@ -66,7 +66,7 @@ impl ArrayPlugin for ALPPatchedPlugin {
6666
parts.children,
6767
session,
6868
)?)
69-
.map_err(|_| vortex_err!(Serde: "ALP plugin should only deserialize vortex.alp"))?;
69+
.map_err(|_| vortex_err!("ALP plugin should only deserialize vortex.alp"))?;
7070

7171
// Check if there are interior patches to externalize.
7272
let Some(patches) = alp_array.patches() else {
@@ -164,13 +164,15 @@ mod tests {
164164

165165
assert_arrays_eq!(deserialized, parray, &mut SESSION.create_execution_ctx());
166166

167-
let patched: PatchedArray = deserialized.try_downcast().map_err(
168-
|a| vortex_err!(MismatchedTypes: "Expected Patched, got {}", a.encoding_id()),
169-
)?;
167+
let patched: PatchedArray = deserialized
168+
.try_downcast()
169+
.map_err(|a| vortex_err!("Expected Patched, got {}", a.encoding_id()))?;
170170

171-
let inner_alp: ALPArray = patched.inner().clone().try_downcast().map_err(
172-
|a| vortex_err!(MismatchedTypes: "Expected inner ALP, got {}", a.encoding_id()),
173-
)?;
171+
let inner_alp: ALPArray = patched
172+
.inner()
173+
.clone()
174+
.try_downcast()
175+
.map_err(|a| vortex_err!("Expected inner ALP, got {}", a.encoding_id()))?;
174176

175177
assert!(
176178
inner_alp.patches().is_none(),
@@ -216,9 +218,9 @@ mod tests {
216218

217219
assert_arrays_eq!(deserialized, parray, &mut SESSION.create_execution_ctx());
218220

219-
let result = deserialized.try_downcast::<ALP>().map_err(
220-
|a| vortex_err!(Serde: "Expected deserialized ALP, got {}", a.encoding_id()),
221-
)?;
221+
let result = deserialized
222+
.try_downcast::<ALP>()
223+
.map_err(|a| vortex_err!("Expected deserialized ALP, got {}", a.encoding_id()))?;
222224

223225
assert!(result.patches().is_none(), "Result should not have patches");
224226

‎encodings/alp/src/alp_rd/array.rs‎

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl VTable for ALPRD {
122122
}
123123

124124
fn buffer(_array: ArrayView<'_, Self>, idx: usize) -> BufferHandle {
125-
vortex_panic!(OutOfBounds: "ALPRDArray buffer index {idx} out of bounds")
125+
vortex_panic!("ALPRDArray buffer index {idx} out of bounds")
126126
}
127127

128128
fn buffer_name(_array: ArrayView<'_, Self>, _idx: usize) -> Option<String> {
@@ -174,7 +174,7 @@ impl VTable for ALPRD {
174174
let metadata = ALPRDMetadata::decode(metadata)?;
175175
if children.len() < 2 {
176176
vortex_bail!(
177-
InvalidArgument: "Expected at least 2 children for ALPRD encoding, found {}",
177+
"Expected at least 2 children for ALPRD encoding, found {}",
178178
children.len()
179179
);
180180
}
@@ -185,9 +185,8 @@ impl VTable for ALPRD {
185185
[0..metadata.dict_len as usize]
186186
.iter()
187187
.map(|&i| {
188-
u16::try_from(i).map_err(
189-
|_| vortex_err!(Overflow: "left_parts_dictionary code {i} does not fit in u16"),
190-
)
188+
u16::try_from(i)
189+
.map_err(|_| vortex_err!("left_parts_dictionary code {i} does not fit in u16"))
191190
})
192191
.try_collect()?;
193192

@@ -198,7 +197,7 @@ impl VTable for ALPRD {
198197
DType::Primitive(PType::F64, _) => {
199198
DType::Primitive(PType::U64, Nullability::NonNullable)
200199
}
201-
_ => vortex_bail!(MismatchedTypes: "Expected f32 or f64 dtype, got {:?}", dtype),
200+
_ => vortex_bail!("Expected f32 or f64 dtype, got {:?}", dtype),
202201
};
203202
let right_parts = children.get(1, &right_parts_dtype, len)?;
204203

@@ -224,7 +223,7 @@ impl VTable for ALPRD {
224223
left_parts_dictionary,
225224
u8::try_from(metadata.right_bit_width).map_err(|_| {
226225
vortex_err!(
227-
Overflow: "right_bit_width {} out of u8 range",
226+
"right_bit_width {} out of u8 range",
228227
metadata.right_bit_width
229228
)
230229
})?,
@@ -478,18 +477,18 @@ fn validate_parts(
478477
left_parts_patches: Option<&Patches>,
479478
) -> VortexResult<()> {
480479
if !dtype.is_float() {
481-
vortex_bail!(InvalidArgument: "ALPRDArray given invalid DType ({dtype})");
480+
vortex_bail!("ALPRDArray given invalid DType ({dtype})");
482481
}
483482

484-
vortex_ensure_eq!(left_parts.len(), len, InvalidArgument);
485-
vortex_ensure_eq!(right_parts.len(), len, InvalidArgument);
483+
vortex_ensure_eq!(left_parts.len(), len);
484+
vortex_ensure_eq!(right_parts.len(), len);
486485

487486
if !left_parts.dtype().is_unsigned_int() {
488-
vortex_bail!(InvalidArgument: "left_parts dtype must be uint");
487+
vortex_bail!("left_parts dtype must be uint");
489488
}
490489
if dtype.is_nullable() != left_parts.dtype().is_nullable() {
491490
vortex_bail!(
492-
InvalidArgument: "ALPRDArray dtype nullability ({}) must match left_parts dtype nullability ({})",
491+
"ALPRDArray dtype nullability ({}) must match left_parts dtype nullability ({})",
493492
dtype,
494493
left_parts.dtype()
495494
);
@@ -498,16 +497,12 @@ fn validate_parts(
498497
let expected_right_parts_dtype = match dtype {
499498
DType::Primitive(PType::F32, _) => DType::Primitive(PType::U32, Nullability::NonNullable),
500499
DType::Primitive(PType::F64, _) => DType::Primitive(PType::U64, Nullability::NonNullable),
501-
_ => vortex_bail!(MismatchedTypes: "Expected f32 or f64 dtype, got {:?}", dtype),
500+
_ => vortex_bail!("Expected f32 or f64 dtype, got {:?}", dtype),
502501
};
503-
vortex_ensure_eq!(
504-
right_parts.dtype(),
505-
&expected_right_parts_dtype,
506-
MismatchedTypes
507-
);
502+
vortex_ensure_eq!(right_parts.dtype(), &expected_right_parts_dtype);
508503

509504
if let Some(patches) = left_parts_patches {
510-
vortex_ensure_eq!(patches.array_len(), len, InvalidArgument);
505+
vortex_ensure_eq!(patches.array_len(), len);
511506
// Left-parts exceptions are always all-valid and are stored as the non-nullable left-parts
512507
// dtype. Requiring that exact dtype (rather than ignoring nullability) means each
513508
// construction path must produce correct patches, removing the need to normalize them.
@@ -516,7 +511,7 @@ fn validate_parts(
516511
vortex_ensure_eq!(
517512
patches.dtype(),
518513
&expected,
519-
MismatchedTypes: "patches dtype must be the non-nullable left_parts dtype"
514+
"patches dtype must be the non-nullable left_parts dtype"
520515
);
521516
}
522517

‎encodings/alp/src/alp_rd/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ where
150150
T::UINT: NativePType,
151151
{
152152
if left_parts.len() != right_parts.len() {
153-
vortex_panic!(AssertionFailed: "alp_rd_decode: left_parts.len != right_parts.len");
153+
vortex_panic!("alp_rd_decode: left_parts.len != right_parts.len");
154154
}
155155

156156
if let Some(patches) = left_parts_patches {

‎encodings/bytebool/src/array.rs‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ impl VTable for ByteBool {
8585
fn buffer(array: ArrayView<'_, Self>, idx: usize) -> BufferHandle {
8686
match idx {
8787
0 => array.buffer().clone(),
88-
_ => vortex_panic!(OutOfBounds: "ByteBoolArray buffer index {idx} out of bounds"),
88+
_ => vortex_panic!("ByteBoolArray buffer index {idx} out of bounds"),
8989
}
9090
}
9191

9292
fn buffer_name(_array: ArrayView<'_, Self>, idx: usize) -> Option<String> {
9393
match idx {
9494
0 => Some("values".to_string()),
95-
_ => vortex_panic!(OutOfBounds: "ByteBoolArray buffer_name index {idx} out of bounds"),
95+
_ => vortex_panic!("ByteBoolArray buffer_name index {idx} out of bounds"),
9696
}
9797
}
9898

@@ -101,7 +101,7 @@ impl VTable for ByteBool {
101101
array: ArrayView<'_, Self>,
102102
buffers: &[BufferHandle],
103103
) -> VortexResult<ArrayParts<Self>> {
104-
vortex_ensure_eq!(buffers.len(), 1, InvalidArgument);
104+
vortex_ensure_eq!(buffers.len(), 1);
105105
let data = ByteBoolData::new(buffers[0].clone());
106106
Ok(ArrayParts::new(
107107
self.clone(),
@@ -130,7 +130,7 @@ impl VTable for ByteBool {
130130
) -> VortexResult<ArrayParts<Self>> {
131131
if !metadata.is_empty() {
132132
vortex_bail!(
133-
InvalidArgument: "ByteBoolArray expects empty metadata, got {} bytes",
133+
"ByteBoolArray expects empty metadata, got {} bytes",
134134
metadata.len()
135135
);
136136
}
@@ -140,11 +140,11 @@ impl VTable for ByteBool {
140140
let validity = children.get(0, &Validity::DTYPE, len)?;
141141
Validity::Array(validity)
142142
} else {
143-
vortex_bail!(MismatchedTypes: "Expected 0 or 1 child, got {}", children.len());
143+
vortex_bail!("Expected 0 or 1 child, got {}", children.len());
144144
};
145145

146146
if buffers.len() != 1 {
147-
vortex_bail!(InvalidArgument: "Expected 1 buffer, got {}", buffers.len());
147+
vortex_bail!("Expected 1 buffer, got {}", buffers.len());
148148
}
149149
let buffer = buffers[0].clone();
150150

@@ -261,10 +261,10 @@ impl ByteBoolData {
261261
len: usize,
262262
) -> VortexResult<()> {
263263
let expected_dtype = DType::Bool(validity.nullability());
264-
vortex_ensure_eq!(dtype, &expected_dtype, MismatchedTypes);
265-
vortex_ensure_eq!(buffer.len(), len, InvalidArgument);
264+
vortex_ensure_eq!(dtype, &expected_dtype);
265+
vortex_ensure_eq!(buffer.len(), len);
266266
if let Some(vlen) = validity.maybe_len() {
267-
vortex_ensure_eq!(vlen, len, InvalidArgument);
267+
vortex_ensure_eq!(vlen, len);
268268
}
269269
Ok(())
270270
}

0 commit comments

Comments
 (0)