feat(storage): classify typed storage failures - #524
Open
ragnorc wants to merge 3 commits into
Open
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a8a4a57. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Implements the accepted RFC-038 from #523.
OmniError::Lance(String)with exhaustiveOmniError::Storage(StorageFailure)StorageFailureKindtaxonomy without adding generic retry/replay semanticsThis is the clean replacement for #491. It starts from current
main, preserves the crash-safe initialization work and current Blob/manifest implementations, and does not port the obsolete Blob code or conflict blocks from that PR.Implementation notes
Unknownis_transient()means exactlykind == TransientExternalBlobPolicyandExternalBlobSourceremain separate user-supplied dependency boundariesFrom<lance::Error>,From<ArrowError>, andFrom<DataFusionError>implementationsValidation
cargo test -p omnigraph-storage --lockedRUST_MIN_STACK=16777216 cargo test --workspace --locked --features omnigraph-engine/failpoints,omnigraph-cluster/failpoints-D warnings -W clippy::dbg_macrocargo test -p omnigraph-server --locked --features awscargo fmt --all --checkgit diff --checkThe stack override is required for the full macOS debug suite: without it,
branch_merge_with_blob_columns_preserves_blob_dataoverflows the default test-thread stack on both the acceptedmainbaseline and this branch. The isolated test and the complete workspace suite pass with the larger stack.Supersedes #491.
Note
High Risk
Touches the universal storage and Lance error path across engine, manifest publish/recovery, and HTTP/CLI surfaces; misclassification could change retry behavior or user-visible error categories despite message-preservation goals.
Overview
Implements RFC-038 by replacing the string-only
OmniError::Lancevariant withOmniError::Storage(StorageFailure), where each failure carries a closedStorageFailureKind(transient, configuration, not found, precondition, permanent, unknown) plus a complete diagnostic message that stays the same for operators and HTTP 500 bodies.omnigraph-storageadds bounded typed traversal (max eight source links) overstd::io::Errorandobject_store::Error, maps adapter failures toStorageError::Backend/ structuredIo, and drops the dedicatedCreateIfAbsentUnsupportedvariant in favor of classified I/O messages.OmniErrorgains explicit converters (storage,storage_context,storage_namespace,datafusion,datafusion_internal,arrow_internal) so Lance, namespace, object-store, and I/O evidence classify without blanketFromimpls.RetryableCommitConflictstays separate from generic Lance precondition conflicts; manifest publish retry vocabulary remains row-level CAS only.Call sites across manifest, recovery, table ops, merge/mutation/export, and blob paths switch from ad-hoc Lance strings to the helpers; many former “Lance” cases now correctly surface as manifest internal, blob integrity, or DataFusion user errors. Server and CLI map
Storageviafailure.to_string()(nostorage:double-prefix); blob tests still hide physical URIs on internal paths.Adds broad unit coverage for I/O/object-store/Lance/namespace matrices, CLI message preservation, and API error mapping tests.
Reviewed by Cursor Bugbot for commit 1f8a84a. Bugbot is set up for automated code reviews on this repo. Configure here.
Greptile Summary
Implements RFC-038’s typed storage-failure model across the storage adapter, core engine, server, and CLI.
StorageFailureand a closed failure-kind taxonomy.Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD E[Typed backend or engine error] --> C{Classification boundary} C -->|object_store or std::io| S[StorageFailureKind] C -->|Lance storage or namespace evidence| S C -->|DataFusion user error| D[DataFusion category] C -->|Arrow or engine invariant| I[Internal domain category] S --> O[OmniError::Storage] D --> Q[OmniError::DataFusion] I --> M[Manifest or Blob internal error] O --> H[HTTP 500 with complete diagnostic] Q --> B[HTTP 400 query error] M --> HReviews (3): Last reviewed commit: "fix(storage): preserve internal failure ..." | Re-trigger Greptile
Context used (3)