Implements plan §13.1 step 4: cross-index verification between live and shadow indexes during resharding. This reuses §13.8's bucketed-Merkle machinery with PK-keyed (not shard-keyed) bucketing to compare indexes with different shard counts. Key changes: - ReshardExecutor::run_verify now uses AntiEntropyReconciler's compare_index_buckets method to perform cross-index comparison - Added VerificationFailed error variant to MiroirError - Exposed executor module via pub mod in reshard.rs - Added helper function hash_pk_to_shard for mismatch detail reporting - Added 6 acceptance tests for PK-keyed bucketing, content hash canonicalization, and verify result structure Acceptance criteria: - Cross-index PK set comparison: live PK set == shadow PK set - Content hash matching: for each PK, content_hash matches - PK-keyed bucketing: independent of shard count S - Reuses §13.8 bucketed-Merkle machinery Closes: miroir-uhj.1.4
109 lines
2.7 KiB
Rust
109 lines
2.7 KiB
Rust
//! Error types for Miroir.
|
|
|
|
use thiserror::Error;
|
|
|
|
/// Result type alias for Miroir operations.
|
|
pub type Result<T> = std::result::Result<T, MiroirError>;
|
|
|
|
/// Core error type for Miroir.
|
|
#[derive(Error, Debug)]
|
|
pub enum MiroirError {
|
|
/// Configuration error.
|
|
#[error("configuration error: {0}")]
|
|
Config(String),
|
|
|
|
/// Topology error.
|
|
#[error("topology error: {0}")]
|
|
Topology(String),
|
|
|
|
/// Routing error.
|
|
#[error("routing error: {0}")]
|
|
Routing(String),
|
|
|
|
/// Merge error.
|
|
#[error("merge error: {0}")]
|
|
Merge(String),
|
|
|
|
/// Task registry error.
|
|
#[error("task error: {0}")]
|
|
Task(String),
|
|
|
|
/// Task store error.
|
|
#[error("task store error: {0}")]
|
|
TaskStore(String),
|
|
|
|
/// IO error.
|
|
#[error("IO error: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
|
|
/// JSON serialization/deserialization error.
|
|
#[error("JSON error: {0}")]
|
|
Json(#[from] serde_json::Error),
|
|
|
|
/// SQLite error.
|
|
#[error("SQLite error: {0}")]
|
|
Sqlite(#[from] rusqlite::Error),
|
|
|
|
/// Redis error.
|
|
#[error("Redis error: {0}")]
|
|
Redis(String),
|
|
|
|
/// Schema version mismatch.
|
|
#[error("schema version {store_version} is ahead of binary version {binary_version}; cannot safely start. Restore from backup or upgrade binary.")]
|
|
SchemaVersionAhead {
|
|
store_version: i64,
|
|
binary_version: i64,
|
|
},
|
|
|
|
/// Migration error.
|
|
#[error("migration error: {0}")]
|
|
Migration(String),
|
|
|
|
/// Not found error.
|
|
#[error("{0} not found")]
|
|
NotFound(String),
|
|
|
|
/// Invalid state error.
|
|
#[error("invalid state: {0}")]
|
|
InvalidState(String),
|
|
|
|
/// Invalid request error.
|
|
#[error("invalid request: {0}")]
|
|
InvalidRequest(String),
|
|
|
|
/// Idempotency key already used with different body.
|
|
#[error("idempotency key reused with different body")]
|
|
IdempotencyKeyReused,
|
|
|
|
/// Too many pending queries.
|
|
#[error("too many pending queries")]
|
|
TooManyPendingQueries,
|
|
|
|
/// Multi-target alias is not writable.
|
|
#[error("multi-target alias is not writable")]
|
|
MultiAliasNotWritable,
|
|
|
|
/// Settings divergence detected.
|
|
#[error("settings divergence detected across nodes")]
|
|
SettingsDivergence,
|
|
|
|
/// Settings version stale.
|
|
#[error("settings version stale")]
|
|
SettingsVersionStale,
|
|
|
|
/// Tenant not allowed.
|
|
#[error("tenant '{tenant}' not allowed: {reason}")]
|
|
TenantNotAllowed { tenant: String, reason: String },
|
|
|
|
/// Discovery error.
|
|
#[error("discovery error: {0}")]
|
|
Discovery(String),
|
|
|
|
/// Anti-entropy error.
|
|
#[error("anti-entropy error: {0}")]
|
|
AntiEntropy(String),
|
|
|
|
/// Verification error (for resharding cross-index verification).
|
|
#[error("verification failed: {0}")]
|
|
VerificationFailed(String),
|
|
}
|