feat: add DecodeFieldError/ReadFileError wrappers for error context#6128
feat: add DecodeFieldError/ReadFileError wrappers for error context#6128koriyoshi2041 wants to merge 2 commits intolance-format:mainfrom
Conversation
…r context
Add wrapper error types that provide contextual information when decoding
errors occur:
- DecodeFieldError: wraps errors with field name and field id, applied at
field scheduler creation points in both structural and legacy decode paths
- ReadFileError: wraps errors with file path, applied at FileReader's
read_tasks and read_stream_projected_blocking entry points
This produces error chains like:
failed to read file 'data.lance'
Caused by:
0: failed to decode field 'age' (id=10)
1: number out of range
Closes lance-format#5602
PR ReviewGood approach following the error wrapping pattern from the linked blog post. The IssuesP1 — Incomplete wrapping in legacy decode path The structural path wraps child field errors for Struct, List, FixedSizeList, and Map. But in the legacy path, only Struct children (line ~990) get wrapped. The legacy let items_scheduler =
self.create_legacy_field_scheduler(&list_field.children[0], column_infos, buffers)?;This should also wrap with P1 — Both NitThe |
- Wrap child field errors with DecodeFieldError in legacy list decode path (create_list_scheduler), matching the structural path's coverage - Use Error::wrapped() instead of Error::io_source() in both From<DecodeFieldError> and From<ReadFileError> to preserve the original error's category instead of converting everything to IO - Restore accidentally deleted "test coalesce indices to ranges" comment
|
Thanks for the thorough review! All three issues have been addressed in the latest commit:
All 428 tests pass (362 lance-encoding + 66 lance-file). |
Summary
Adds two wrapper error types to provide better context when decoding errors occur, as described in #5602:
DecodeFieldError(lance-encoding/src/decoder.rs): wraps errors with field name and field id. Applied at field scheduler creation in both structural and legacy decode paths (Struct, List, FixedSizeList, Map).ReadFileError(lance-file/src/reader.rs): wraps errors with file path. Applied atFileReader::read_tasksandread_stream_projected_blockingentry points.FileReadernow stores the file path.Both implement
std::error::Errorwith proper source chaining andFrom<...> for lance_core::Error, producing error chains like:Design follows the approach from https://sabrinajewson.org/blog/errors as referenced in the issue.
Test plan
DecodeFieldErrordisplay, source chain, and conversion tolance_core::Error(3 tests)ReadFileErrordisplay, source chain with nestedDecodeFieldError, and conversion tolance_core::Error(3 tests)cargo fmt --checkpassescargo clippy --all-targets -p lance-encoding -p lance-filepassesCloses #5602