Skip to main content

icydb_core/error/
mod.rs

1//! Module: error
2//!
3//! Defines the canonical runtime error taxonomy for `icydb-core`.
4//! This module owns the shared error classes, origins, details, and
5//! constructor entry points used across storage, planning, execution, and
6//! serialization boundaries.
7
8#[cfg(test)]
9mod tests;
10
11use icydb_diagnostic_code as diagnostic_code;
12use std::fmt;
13
14pub(crate) const COMPACT_QUERY_DIAGNOSTIC_MESSAGE: &str = "query diagnostic";
15const COMPACT_RUNTIME_DIAGNOSTIC_MESSAGE: &str = "runtime diagnostic";
16const COMPACT_STORE_DIAGNOSTIC_MESSAGE: &str = "store diagnostic";
17const COMPACT_INDEX_DIAGNOSTIC_MESSAGE: &str = "index diagnostic";
18const COMPACT_SERIALIZE_DIAGNOSTIC_MESSAGE: &str = "serialize diagnostic";
19const COMPACT_IDENTITY_DIAGNOSTIC_MESSAGE: &str = "identity diagnostic";
20
21const fn compact_message_for(_class: ErrorClass, origin: ErrorOrigin) -> &'static str {
22    match origin {
23        ErrorOrigin::Serialize => COMPACT_SERIALIZE_DIAGNOSTIC_MESSAGE,
24        ErrorOrigin::Store => COMPACT_STORE_DIAGNOSTIC_MESSAGE,
25        ErrorOrigin::Index => COMPACT_INDEX_DIAGNOSTIC_MESSAGE,
26        ErrorOrigin::Identity => COMPACT_IDENTITY_DIAGNOSTIC_MESSAGE,
27        ErrorOrigin::Query | ErrorOrigin::Planner | ErrorOrigin::Response => {
28            COMPACT_QUERY_DIAGNOSTIC_MESSAGE
29        }
30        ErrorOrigin::Cursor
31        | ErrorOrigin::Recovery
32        | ErrorOrigin::Executor
33        | ErrorOrigin::Interface => COMPACT_RUNTIME_DIAGNOSTIC_MESSAGE,
34    }
35}
36
37// ============================================================================
38// INTERNAL ERROR TAXONOMY — ARCHITECTURAL CONTRACT
39// ============================================================================
40//
41// This file defines the canonical runtime error classification system for
42// icydb-core. It is the single source of truth for:
43//
44//   • ErrorClass   (semantic domain)
45//   • ErrorOrigin  (subsystem boundary)
46//   • Structured detail payloads
47//   • Canonical constructor entry points
48//
49// -----------------------------------------------------------------------------
50// DESIGN INTENT
51// -----------------------------------------------------------------------------
52//
53// 1. InternalError is a *taxonomy carrier*, not a formatting utility.
54//
55//    - ErrorClass represents semantic meaning (corruption, invariant_violation,
56//      unsupported, etc).
57//    - ErrorOrigin represents the subsystem boundary (store, index, query,
58//      executor, serialize, interface, etc).
59//    - The (class, origin) pair must remain stable and intentional.
60//
61// 2. Call sites MUST prefer canonical constructors.
62//
63//    Do NOT construct errors manually via:
64//        InternalError::new(class, origin)
65//    unless you are defining a new canonical helper here.
66//
67//    If a pattern appears more than once, centralize it here.
68//
69// 3. Constructors in this file must represent real architectural boundaries.
70//
71//    Add a new helper ONLY if it:
72//
73//      • Encodes a cross-cutting invariant,
74//      • Represents a subsystem boundary,
75//      • Or prevents taxonomy drift across call sites.
76//
77//    Do NOT add feature-specific helpers.
78//    Do NOT add one-off formatting helpers.
79//    Do NOT turn this file into a generic message factory.
80//
81// 4. ErrorDetail must align with ErrorOrigin.
82//
83//    If detail is present, it MUST correspond to the origin.
84//    Do not attach mismatched detail variants.
85//
86// 5. Plan-layer errors are NOT runtime failures.
87//
88//    PlanError and CursorPlanError must be translated into
89//    executor/query invariants via the canonical mapping functions.
90//    Do not leak plan-layer error types across execution boundaries.
91//
92// 6. Preserve taxonomy stability.
93//
94//    Do NOT:
95//      • Merge error classes.
96//      • Reclassify corruption as internal.
97//      • Downgrade invariant violations.
98//      • Introduce ambiguous class/origin combinations.
99//
100//    Any change to ErrorClass or ErrorOrigin is an architectural change
101//    and must be reviewed accordingly.
102//
103// -----------------------------------------------------------------------------
104// NON-GOALS
105// -----------------------------------------------------------------------------
106//
107// This is NOT:
108//
109//   • A public API contract.
110//   • A generic error abstraction layer.
111//   • A feature-specific message builder.
112//   • A dumping ground for temporary error conversions.
113//
114// -----------------------------------------------------------------------------
115// MAINTENANCE GUIDELINES
116// -----------------------------------------------------------------------------
117//
118// When modifying this file:
119//
120//   1. Ensure classification semantics remain consistent.
121//   2. Avoid constructor proliferation.
122//   3. Prefer narrow, origin-specific helpers over ad-hoc new(...).
123//   4. Keep formatting minimal and standardized.
124//   5. Keep this file boring and stable.
125//
126// If this file grows rapidly, something is wrong at the call sites.
127//
128// ============================================================================
129
130///
131/// InternalError
132///
133/// Structured runtime error with a stable internal classification.
134/// Not a stable API; intended for internal use and may change without notice.
135///
136
137pub struct InternalError {
138    pub(crate) class: ErrorClass,
139    pub(crate) origin: ErrorOrigin,
140
141    /// Optional structured error detail.
142    /// The variant (if present) must correspond to `origin`.
143    pub(crate) detail: Option<ErrorDetail>,
144}
145
146#[expect(
147    clippy::missing_const_for_fn,
148    reason = "internal error constructors stay non-const so compact diagnostic construction does not force const churn across subsystem helper seams"
149)]
150impl InternalError {
151    /// Construct an InternalError with optional origin-specific detail.
152    /// This constructor provides default StoreError details for certain
153    /// (class, origin) combinations but does not guarantee a detail payload.
154    #[must_use]
155    #[cold]
156    #[inline(never)]
157    pub fn new(class: ErrorClass, origin: ErrorOrigin) -> Self {
158        let detail = match (class, origin) {
159            (ErrorClass::Corruption, ErrorOrigin::Store) => {
160                Some(ErrorDetail::Store(StoreError::Corrupt))
161            }
162            (ErrorClass::InvariantViolation, ErrorOrigin::Store) => {
163                Some(ErrorDetail::Store(StoreError::InvariantViolation))
164            }
165            _ => None,
166        };
167
168        Self {
169            class,
170            origin,
171            detail,
172        }
173    }
174
175    /// Return the internal error class taxonomy.
176    #[must_use]
177    pub const fn class(&self) -> ErrorClass {
178        self.class
179    }
180
181    /// Return the internal error origin taxonomy.
182    #[must_use]
183    pub const fn origin(&self) -> ErrorOrigin {
184        self.origin
185    }
186
187    /// Return the rendered internal error message.
188    #[must_use]
189    pub const fn message(&self) -> &'static str {
190        compact_message_for(self.class, self.origin)
191    }
192
193    /// Return the optional structured detail payload.
194    #[must_use]
195    pub const fn detail(&self) -> Option<&ErrorDetail> {
196        self.detail.as_ref()
197    }
198
199    /// Return compact diagnostic identity for this internal error.
200    #[must_use]
201    pub fn diagnostic(&self) -> diagnostic_code::Diagnostic {
202        diagnostic_code::Diagnostic::new(
203            self.diagnostic_code(),
204            self.origin.diagnostic_origin(),
205            self.detail
206                .as_ref()
207                .and_then(ErrorDetail::diagnostic_detail),
208        )
209    }
210
211    /// Return the compact diagnostic code for this internal error.
212    #[must_use]
213    pub fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
214        self.detail.as_ref().map_or_else(
215            || self.class.diagnostic_code(self.origin),
216            ErrorDetail::diagnostic_code,
217        )
218    }
219
220    /// Consume and return the rendered internal error message.
221    #[must_use]
222    pub fn into_message(self) -> String {
223        self.message().to_string()
224    }
225
226    /// Construct an error while preserving an explicit class/origin taxonomy pair.
227    #[cold]
228    #[inline(never)]
229    pub(crate) fn classified(class: ErrorClass, origin: ErrorOrigin) -> Self {
230        Self::new(class, origin)
231    }
232
233    /// Rebuild this error with a new origin while preserving class taxonomy.
234    ///
235    /// Origin-scoped detail payloads are intentionally dropped when re-origining.
236    #[cold]
237    #[inline(never)]
238    pub(crate) fn with_origin(self, origin: ErrorOrigin) -> Self {
239        Self::classified(self.class, origin)
240    }
241
242    /// Construct an index-origin invariant violation.
243    #[cold]
244    #[inline(never)]
245    pub(crate) fn index_invariant() -> Self {
246        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Index)
247    }
248
249    /// Construct the canonical index field-count invariant for key building.
250    pub(crate) fn index_key_field_count_exceeds_max(
251        _index_name: &str,
252        _field_count: usize,
253        _max_fields: usize,
254    ) -> Self {
255        Self::index_invariant()
256    }
257
258    /// Construct the canonical index-key source-field-missing-on-model invariant.
259    pub(crate) fn index_key_item_field_missing_on_entity_model(_field: &str) -> Self {
260        Self::index_invariant()
261    }
262
263    /// Construct the canonical index-key source-field-missing-on-row invariant.
264    pub(crate) fn index_key_item_field_missing_on_lookup_row(_field: &str) -> Self {
265        Self::index_invariant()
266    }
267
268    /// Construct the canonical index-expression source-type mismatch invariant.
269    pub(crate) fn index_expression_source_type_mismatch(
270        _index_name: &str,
271        _expression: impl Sized,
272        _expected: impl Sized,
273        _source_label: &str,
274    ) -> Self {
275        Self::index_invariant()
276    }
277
278    /// Construct a planner-origin invariant violation for executor-boundary
279    /// contract drift.
280    #[cold]
281    #[inline(never)]
282    pub(crate) fn planner_executor_invariant() -> Self {
283        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Planner)
284    }
285
286    /// Construct a query-origin invariant violation for executor-boundary
287    /// contract drift.
288    #[cold]
289    #[inline(never)]
290    pub(crate) fn query_executor_invariant() -> Self {
291        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Query)
292    }
293
294    /// Construct a cursor-origin invariant violation for executor-boundary
295    /// contract drift.
296    #[cold]
297    #[inline(never)]
298    pub(crate) fn cursor_executor_invariant() -> Self {
299        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Cursor)
300    }
301
302    /// Construct an executor-origin invariant violation.
303    #[cold]
304    #[inline(never)]
305    pub(crate) fn executor_invariant() -> Self {
306        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Executor)
307    }
308
309    /// Construct an executor-origin conflict.
310    #[cold]
311    #[inline(never)]
312    pub(crate) fn executor_conflict() -> Self {
313        Self::new(ErrorClass::Conflict, ErrorOrigin::Executor)
314    }
315
316    /// Construct an executor-origin internal error.
317    #[cold]
318    #[inline(never)]
319    pub(crate) fn executor_internal() -> Self {
320        Self::new(ErrorClass::Internal, ErrorOrigin::Executor)
321    }
322
323    /// Construct an executor-origin unsupported error.
324    #[cold]
325    #[inline(never)]
326    pub(crate) fn executor_unsupported() -> Self {
327        Self::new(ErrorClass::Unsupported, ErrorOrigin::Executor)
328    }
329
330    /// Construct an executor-origin save-preflight primary-key missing invariant.
331    pub(crate) fn mutation_entity_primary_key_missing(
332        _entity_path: &str,
333        _field_name: &str,
334    ) -> Self {
335        Self::executor_invariant()
336    }
337
338    /// Construct an executor-origin save-preflight primary-key invalid-value invariant.
339    pub(crate) fn mutation_entity_primary_key_invalid_value(
340        _entity_path: &str,
341        _field_name: &str,
342        _value: &crate::value::Value,
343    ) -> Self {
344        Self::executor_invariant()
345    }
346
347    /// Construct an executor-origin save-preflight primary-key type mismatch invariant.
348    pub(crate) fn mutation_entity_primary_key_type_mismatch(
349        _entity_path: &str,
350        _field_name: &str,
351        _value: &crate::value::Value,
352    ) -> Self {
353        Self::executor_invariant()
354    }
355
356    /// Construct an executor-origin save-preflight primary-key identity mismatch invariant.
357    pub(crate) fn mutation_entity_primary_key_mismatch(
358        _entity_path: &str,
359        _field_name: &str,
360        _field_value: &crate::value::Value,
361        _identity_key: &crate::value::Value,
362    ) -> Self {
363        Self::executor_invariant()
364    }
365
366    /// Construct an executor-origin save-preflight field-missing invariant.
367    pub(crate) fn mutation_entity_field_missing(
368        _entity_path: &str,
369        _field_name: &str,
370        _indexed: bool,
371    ) -> Self {
372        Self::executor_invariant()
373    }
374
375    /// Construct an executor-origin sparse structural patch required-field invariant.
376    pub(crate) fn mutation_structural_patch_required_field_missing(
377        _entity_path: &str,
378        _field_name: &str,
379    ) -> Self {
380        Self::executor_invariant()
381    }
382
383    /// Construct an executor-origin save-preflight field-type mismatch invariant.
384    pub(crate) fn mutation_entity_field_type_mismatch(
385        _entity_path: &str,
386        _field_name: &str,
387        _value: &crate::value::Value,
388    ) -> Self {
389        Self::executor_invariant()
390    }
391
392    /// Construct an executor-origin generated-field authored-write rejection.
393    pub(crate) fn mutation_generated_field_explicit(_entity_path: &str, _field_name: &str) -> Self {
394        Self::executor_unsupported()
395    }
396
397    /// Construct an executor-origin typed create omission rejection.
398    #[must_use]
399    pub fn mutation_create_missing_authored_fields(_entity_path: &str, _field_names: &str) -> Self {
400        Self::executor_unsupported()
401    }
402
403    /// Construct an executor-origin mutation result invariant.
404    ///
405    /// This constructor lands ahead of the public structural mutation surface,
406    /// so the library target may not route through it until that caller exists.
407    pub(crate) fn mutation_structural_after_image_invalid(
408        _entity_path: &str,
409        _data_key: impl Sized,
410        _detail: impl Sized,
411    ) -> Self {
412        Self::executor_invariant()
413    }
414
415    /// Construct an executor-origin mutation unknown-field invariant.
416    pub(crate) fn mutation_structural_field_unknown(_entity_path: &str, _field_name: &str) -> Self {
417        Self::executor_invariant()
418    }
419
420    /// Construct an executor-origin save-preflight decimal-scale unsupported error.
421    pub(crate) fn mutation_decimal_scale_mismatch(
422        _entity_path: &str,
423        _field_name: &str,
424        _expected_scale: impl Sized,
425        _actual_scale: impl Sized,
426    ) -> Self {
427        Self::executor_unsupported()
428    }
429
430    /// Construct an executor-origin save-preflight text-length unsupported error.
431    pub(crate) fn mutation_text_max_len_exceeded(
432        _entity_path: &str,
433        _field_name: &str,
434        _max_len: impl Sized,
435        _actual_len: impl Sized,
436    ) -> Self {
437        Self::executor_unsupported()
438    }
439
440    /// Construct an executor-origin save-preflight set-encoding invariant.
441    pub(crate) fn mutation_set_field_list_required(_entity_path: &str, _field_name: &str) -> Self {
442        Self::executor_invariant()
443    }
444
445    /// Construct an executor-origin save-preflight set-canonicality invariant.
446    pub(crate) fn mutation_set_field_not_canonical(_entity_path: &str, _field_name: &str) -> Self {
447        Self::executor_invariant()
448    }
449
450    /// Construct an executor-origin save-preflight map-encoding invariant.
451    pub(crate) fn mutation_map_field_map_required(_entity_path: &str, _field_name: &str) -> Self {
452        Self::executor_invariant()
453    }
454
455    /// Construct an executor-origin save-preflight map-entry invariant.
456    pub(crate) fn mutation_map_field_entries_invalid(
457        _entity_path: &str,
458        _field_name: &str,
459        _detail: impl Sized,
460    ) -> Self {
461        Self::executor_invariant()
462    }
463
464    /// Construct an executor-origin save-preflight map-canonicality invariant.
465    pub(crate) fn mutation_map_field_entries_not_canonical(
466        _entity_path: &str,
467        _field_name: &str,
468    ) -> Self {
469        Self::executor_invariant()
470    }
471
472    /// Construct a query-origin scalar page invariant for missing order at the cursor boundary.
473    pub(crate) fn scalar_page_cursor_boundary_order_required() -> Self {
474        Self::query_executor_invariant()
475    }
476
477    /// Construct a query-origin scalar page invariant for cursor-before-ordering drift.
478    pub(crate) fn scalar_page_cursor_boundary_after_ordering_required() -> Self {
479        Self::query_executor_invariant()
480    }
481
482    /// Construct a query-origin scalar page invariant for pagination-before-ordering drift.
483    pub(crate) fn scalar_page_pagination_after_ordering_required() -> Self {
484        Self::query_executor_invariant()
485    }
486
487    /// Construct a query-origin load-entrypoint invariant for non-load plans.
488    pub(crate) fn load_executor_load_plan_required() -> Self {
489        Self::query_executor_invariant()
490    }
491
492    /// Construct an executor-origin delete-entrypoint unsupported grouped-mode error.
493    pub(crate) fn delete_executor_grouped_unsupported() -> Self {
494        Self::executor_unsupported()
495    }
496
497    /// Construct a query-origin delete-entrypoint invariant for non-delete plans.
498    pub(crate) fn delete_executor_delete_plan_required() -> Self {
499        Self::query_executor_invariant()
500    }
501
502    /// Construct a query-origin aggregate kernel invariant for fold-mode contract drift.
503    pub(crate) fn aggregate_fold_mode_terminal_contract_required() -> Self {
504        Self::query_executor_invariant()
505    }
506
507    /// Construct a query-origin fast-stream invariant for route kind/request mismatch.
508    pub(crate) fn fast_stream_route_kind_request_match_required() -> Self {
509        Self::query_executor_invariant()
510    }
511
512    /// Construct a query-origin scan invariant for missing index-prefix executable specs.
513    pub(crate) fn secondary_index_prefix_spec_required() -> Self {
514        Self::query_executor_invariant()
515    }
516
517    /// Construct a query-origin scan invariant for missing index-range executable specs.
518    pub(crate) fn index_range_limit_spec_required() -> Self {
519        Self::query_executor_invariant()
520    }
521
522    /// Construct an executor-origin mutation conflict for duplicate atomic save keys.
523    pub(crate) fn mutation_atomic_save_duplicate_key(_entity_path: &str, _key: impl Sized) -> Self {
524        Self::executor_conflict()
525    }
526
527    /// Construct an executor-origin mutation invariant for index-store generation drift.
528    pub(crate) fn mutation_index_store_generation_changed(
529        _expected_generation: u64,
530        _observed_generation: u64,
531    ) -> Self {
532        Self::executor_invariant()
533    }
534
535    /// Construct a planner-origin invariant violation.
536    #[cold]
537    #[inline(never)]
538    pub(crate) fn planner_invariant() -> Self {
539        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Planner)
540    }
541
542    /// Construct a planner-origin invalid-logical-plan invariant.
543    pub(crate) fn query_invalid_logical_plan() -> Self {
544        Self::planner_invariant()
545    }
546
547    /// Construct a store-origin invariant violation.
548    pub(crate) fn store_invariant() -> Self {
549        Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Store)
550    }
551
552    /// Construct the canonical duplicate runtime-hook entity-tag invariant.
553    pub(crate) fn duplicate_runtime_hooks_for_entity_tag(
554        _entity_tag: crate::types::EntityTag,
555    ) -> Self {
556        Self::store_invariant()
557    }
558
559    /// Construct the canonical duplicate runtime-hook entity-path invariant.
560    pub(crate) fn duplicate_runtime_hooks_for_entity_path(_entity_path: &str) -> Self {
561        Self::store_invariant()
562    }
563
564    /// Construct a store-origin internal error.
565    #[cold]
566    #[inline(never)]
567    pub(crate) fn store_internal() -> Self {
568        Self::new(ErrorClass::Internal, ErrorOrigin::Store)
569    }
570
571    /// Construct the canonical unconfigured commit-memory id internal error.
572    pub(crate) fn commit_memory_id_unconfigured() -> Self {
573        Self::store_internal()
574    }
575
576    /// Construct the canonical commit-memory id mismatch internal error.
577    pub(crate) fn commit_memory_id_mismatch(_cached_id: u8, _configured_id: u8) -> Self {
578        Self::store_internal()
579    }
580
581    /// Construct the canonical commit-memory stable-key mismatch internal error.
582    pub(crate) fn commit_memory_stable_key_mismatch(
583        _cached_key: &str,
584        _configured_key: &str,
585    ) -> Self {
586        Self::store_internal()
587    }
588
589    /// Construct a recovery-origin incompatible store-format error.
590    pub(crate) fn recovery_unsupported_database_format(found: Option<u16>, required: u16) -> Self {
591        Self {
592            class: ErrorClass::IncompatiblePersistedFormat,
593            origin: ErrorOrigin::Recovery,
594            detail: Some(ErrorDetail::Recovery(
595                RecoveryErrorDetail::UnsupportedFormatVersion { found, required },
596            )),
597        }
598    }
599
600    /// Construct a recovery-origin malformed store-format marker error.
601    pub(crate) fn recovery_malformed_database_format_marker(
602        reason: RecoveryFormatMarkerError,
603    ) -> Self {
604        Self {
605            class: ErrorClass::Corruption,
606            origin: ErrorOrigin::Recovery,
607            detail: Some(ErrorDetail::Recovery(
608                RecoveryErrorDetail::MalformedFormatMarker { reason },
609            )),
610        }
611    }
612
613    /// Construct a recovery-origin boot control-memory failure.
614    pub(crate) fn recovery_database_format_control_unavailable() -> Self {
615        Self::new(ErrorClass::Internal, ErrorOrigin::Recovery)
616    }
617
618    /// Construct a commit control-memory growth failure.
619    pub(crate) fn commit_control_memory_growth_failed() -> Self {
620        Self::store_internal()
621    }
622
623    /// Construct a store-format memory registration failure.
624    #[cfg(not(test))]
625    pub(crate) fn database_format_memory_registration_failed(_err: impl Sized) -> Self {
626        Self::store_internal()
627    }
628
629    /// Construct the canonical missing rollback-row invariant for delete execution.
630    pub(crate) fn delete_rollback_row_required() -> Self {
631        Self::store_internal()
632    }
633
634    /// Construct the canonical recovery-integrity totals corruption error.
635    pub(crate) fn recovery_integrity_validation_failed(
636        _missing_index_entries: u64,
637        _divergent_index_entries: u64,
638        _orphan_index_references: u64,
639    ) -> Self {
640        Self::store_corruption()
641    }
642
643    /// Construct an index-origin internal error.
644    #[cold]
645    #[inline(never)]
646    pub(crate) fn index_internal() -> Self {
647        Self::new(ErrorClass::Internal, ErrorOrigin::Index)
648    }
649
650    /// Construct the canonical missing old entity-key internal error for structural index removal.
651    pub(crate) fn structural_index_removal_entity_key_required() -> Self {
652        Self::index_internal()
653    }
654
655    /// Construct the canonical missing new entity-key internal error for structural index insertion.
656    pub(crate) fn structural_index_insertion_entity_key_required() -> Self {
657        Self::index_internal()
658    }
659
660    /// Construct the canonical missing old entity-key internal error for index commit-op removal.
661    pub(crate) fn index_commit_op_old_entity_key_required() -> Self {
662        Self::index_internal()
663    }
664
665    /// Construct the canonical missing new entity-key internal error for index commit-op insertion.
666    pub(crate) fn index_commit_op_new_entity_key_required() -> Self {
667        Self::index_internal()
668    }
669
670    /// Construct a query-origin internal error.
671    #[cfg(test)]
672    pub(crate) fn query_internal() -> Self {
673        Self::new(ErrorClass::Internal, ErrorOrigin::Query)
674    }
675
676    /// Construct a query-origin unsupported error.
677    #[cold]
678    #[inline(never)]
679    pub(crate) fn query_unsupported() -> Self {
680        Self::new(ErrorClass::Unsupported, ErrorOrigin::Query)
681    }
682
683    /// Construct a query-origin conflict for execution against a superseded
684    /// accepted schema revision.
685    #[cold]
686    #[inline(never)]
687    pub(crate) fn query_stale_accepted_schema_revision(
688        _expected_revision: u64,
689        _current_revision: Option<u64>,
690    ) -> Self {
691        Self {
692            class: ErrorClass::Conflict,
693            origin: ErrorOrigin::Query,
694            detail: Some(ErrorDetail::Query(QueryErrorDetail::StaleSchemaRevision)),
695        }
696    }
697
698    /// Construct a query-origin SQL DDL admission error with structured detail.
699    #[cold]
700    #[inline(never)]
701    #[cfg(feature = "sql")]
702    pub(crate) fn query_schema_ddl_admission(error: SchemaDdlAdmissionError) -> Self {
703        Self {
704            class: ErrorClass::Unsupported,
705            origin: ErrorOrigin::Query,
706            detail: Some(ErrorDetail::Query(QueryErrorDetail::SchemaDdlAdmission {
707                error,
708            })),
709        }
710    }
711
712    /// Construct a query-origin numeric overflow error with structured detail.
713    #[cold]
714    #[inline(never)]
715    pub(crate) fn query_numeric_overflow() -> Self {
716        Self {
717            class: ErrorClass::Unsupported,
718            origin: ErrorOrigin::Query,
719            detail: Some(ErrorDetail::Query(QueryErrorDetail::NumericOverflow)),
720        }
721    }
722
723    /// Construct a query-origin non-representable numeric result error with
724    /// structured detail.
725    #[cold]
726    #[inline(never)]
727    pub(crate) fn query_numeric_not_representable() -> Self {
728        Self {
729            class: ErrorClass::Unsupported,
730            origin: ErrorOrigin::Query,
731            detail: Some(ErrorDetail::Query(
732                QueryErrorDetail::NumericNotRepresentable,
733            )),
734        }
735    }
736
737    /// Construct a serialize-origin internal error.
738    #[cold]
739    #[inline(never)]
740    pub(crate) fn serialize_internal() -> Self {
741        Self::new(ErrorClass::Internal, ErrorOrigin::Serialize)
742    }
743
744    /// Construct the canonical persisted-row encode internal error.
745    pub(crate) fn persisted_row_encode_failed(_detail: impl Sized) -> Self {
746        Self::persisted_row_encode_internal()
747    }
748
749    /// Construct the compact persisted-row encode internal error.
750    pub(crate) fn persisted_row_encode_internal() -> Self {
751        Self::serialize_internal()
752    }
753
754    /// Construct the canonical persisted-row field encode internal error.
755    pub(crate) fn persisted_row_field_encode_failed(field_name: &str, _detail: impl Sized) -> Self {
756        Self::persisted_row_field_encode_internal(field_name)
757    }
758
759    /// Construct the compact persisted-row field encode internal error.
760    pub(crate) fn persisted_row_field_encode_internal(_field_name: &str) -> Self {
761        Self::persisted_row_encode_internal()
762    }
763
764    /// Construct the canonical bytes(field) value encode internal error.
765    pub(crate) fn bytes_field_value_encode_failed(_detail: impl Sized) -> Self {
766        Self::serialize_internal()
767    }
768
769    /// Construct a store-origin corruption error.
770    #[cold]
771    #[inline(never)]
772    pub(crate) fn store_corruption() -> Self {
773        Self::new(ErrorClass::Corruption, ErrorOrigin::Store)
774    }
775
776    /// Construct a store-origin commit-marker corruption error.
777    pub(crate) fn commit_corruption() -> Self {
778        Self::store_corruption()
779    }
780
781    /// Construct a store-origin commit-marker component corruption error.
782    pub(crate) fn commit_component_corruption() -> Self {
783        Self::commit_corruption()
784    }
785
786    /// Construct the canonical commit-marker id generation internal error.
787    pub(crate) fn commit_id_generation_failed() -> Self {
788        Self::store_internal()
789    }
790
791    /// Construct the canonical commit-marker payload u32-length-limit error.
792    pub(crate) fn commit_marker_payload_exceeds_u32_length_limit() -> Self {
793        Self::store_unsupported()
794    }
795
796    /// Construct the canonical commit-marker component invalid-length corruption error.
797    pub(crate) fn commit_component_length_invalid() -> Self {
798        Self::commit_corruption()
799    }
800
801    /// Construct the canonical commit-marker max-size corruption error.
802    pub(crate) fn commit_marker_exceeds_max_size() -> Self {
803        Self::commit_corruption()
804    }
805
806    /// Construct the canonical commit-control slot max-size unsupported error.
807    pub(crate) fn commit_control_slot_exceeds_max_size() -> Self {
808        Self::store_unsupported()
809    }
810
811    /// Construct the canonical commit-control marker-bytes length-limit error.
812    pub(crate) fn commit_control_slot_marker_bytes_exceed_u32_length_limit() -> Self {
813        Self::store_unsupported()
814    }
815
816    /// Construct the canonical startup index-rebuild invalid-data-key corruption error.
817    pub(crate) fn startup_index_rebuild_invalid_data_key() -> Self {
818        Self::store_corruption()
819    }
820
821    /// Construct an index-origin corruption error.
822    #[cold]
823    #[inline(never)]
824    pub(crate) fn index_corruption() -> Self {
825        Self::new(ErrorClass::Corruption, ErrorOrigin::Index)
826    }
827
828    /// Construct the canonical unique-validation corruption wrapper.
829    pub(crate) fn index_unique_validation_corruption() -> Self {
830        Self::index_plan_index_corruption()
831    }
832
833    /// Construct the canonical structural index-entry corruption wrapper.
834    pub(crate) fn structural_index_entry_corruption() -> Self {
835        Self::index_plan_index_corruption()
836    }
837
838    /// Construct the canonical missing new entity-key invariant during unique validation.
839    pub(crate) fn index_unique_validation_entity_key_required() -> Self {
840        Self::index_invariant()
841    }
842
843    /// Construct the canonical unique-validation structural row-decode corruption error.
844    pub(crate) fn index_unique_validation_row_deserialize_failed() -> Self {
845        Self::index_plan_serialize_corruption()
846    }
847
848    /// Construct the canonical unique-validation primary-key slot decode corruption error.
849    pub(crate) fn index_unique_validation_primary_key_decode_failed() -> Self {
850        Self::index_plan_serialize_corruption()
851    }
852
853    /// Construct the canonical unique-validation stored key rebuild corruption error.
854    pub(crate) fn index_unique_validation_key_rebuild_failed() -> Self {
855        Self::index_plan_serialize_corruption()
856    }
857
858    /// Construct the canonical unique-validation missing-row corruption error.
859    pub(crate) fn index_unique_validation_row_required() -> Self {
860        Self::index_plan_store_corruption()
861    }
862
863    /// Construct the canonical index-only predicate missing-component invariant.
864    pub(crate) fn index_only_predicate_component_required() -> Self {
865        Self::index_invariant()
866    }
867
868    /// Construct the canonical index-scan continuation-envelope invariant.
869    pub(crate) fn index_scan_continuation_anchor_within_envelope_required() -> Self {
870        Self::index_invariant()
871    }
872
873    /// Construct the canonical index-scan continuation-advancement invariant.
874    pub(crate) fn index_scan_continuation_advancement_required() -> Self {
875        Self::index_invariant()
876    }
877
878    /// Construct the canonical index-scan key-decode corruption error.
879    pub(crate) fn index_scan_key_corrupted_during(
880        _context: &'static str,
881        _err: impl Sized,
882    ) -> Self {
883        Self::index_corruption()
884    }
885
886    /// Construct the canonical index-scan missing projection-component invariant.
887    pub(crate) fn index_projection_component_required(
888        _index_name: &str,
889        _component_index: usize,
890    ) -> Self {
891        Self::index_invariant()
892    }
893
894    /// Construct the canonical scan-time index-entry decode corruption error.
895    pub(crate) fn index_entry_decode_failed() -> Self {
896        Self::index_corruption()
897    }
898
899    /// Construct a serialize-origin corruption error.
900    pub(crate) fn serialize_corruption() -> Self {
901        Self::new(ErrorClass::Corruption, ErrorOrigin::Serialize)
902    }
903
904    /// Construct the canonical persisted-row decode corruption error.
905    pub(crate) fn persisted_row_decode_failed(_detail: impl Sized) -> Self {
906        Self::persisted_row_decode_corruption()
907    }
908
909    /// Construct the compact persisted-row decode corruption error.
910    pub(crate) fn persisted_row_decode_corruption() -> Self {
911        Self::serialize_corruption()
912    }
913
914    /// Construct the canonical persisted-row field decode corruption error.
915    pub(crate) fn persisted_row_field_decode_failed(field_name: &str, _detail: impl Sized) -> Self {
916        Self::persisted_row_field_decode_corruption(field_name)
917    }
918
919    /// Construct the compact persisted-row field decode corruption error.
920    pub(crate) fn persisted_row_field_decode_corruption(_field_name: &str) -> Self {
921        Self::persisted_row_decode_corruption()
922    }
923
924    /// Construct the canonical persisted-row field-kind decode corruption error.
925    pub(crate) fn persisted_row_field_kind_decode_failed(
926        field_name: &str,
927        _field_kind: impl fmt::Debug,
928        _detail: impl Sized,
929    ) -> Self {
930        Self::persisted_row_field_decode_corruption(field_name)
931    }
932
933    /// Construct the canonical persisted-row scalar-payload length corruption error.
934    pub(crate) fn persisted_row_field_payload_exact_len_required(field_name: &str) -> Self {
935        Self::persisted_row_field_decode_corruption(field_name)
936    }
937
938    /// Construct the canonical persisted-row scalar-payload empty-body corruption error.
939    pub(crate) fn persisted_row_field_payload_must_be_empty(field_name: &str) -> Self {
940        Self::persisted_row_field_decode_corruption(field_name)
941    }
942
943    /// Construct the canonical persisted-row scalar-payload invalid-byte corruption error.
944    pub(crate) fn persisted_row_field_payload_invalid_byte(field_name: &str) -> Self {
945        Self::persisted_row_field_decode_corruption(field_name)
946    }
947
948    /// Construct the canonical persisted-row scalar-payload non-finite corruption error.
949    pub(crate) fn persisted_row_field_payload_non_finite(field_name: &str) -> Self {
950        Self::persisted_row_field_decode_corruption(field_name)
951    }
952
953    /// Construct the canonical persisted-row scalar-payload out-of-range corruption error.
954    pub(crate) fn persisted_row_field_payload_out_of_range(field_name: &str) -> Self {
955        Self::persisted_row_field_decode_corruption(field_name)
956    }
957
958    /// Construct the canonical persisted-row invalid text payload corruption error.
959    pub(crate) fn persisted_row_field_text_payload_invalid_utf8(field_name: &str) -> Self {
960        Self::persisted_row_field_decode_corruption(field_name)
961    }
962
963    /// Construct the canonical persisted-row structural slot-lookup invariant.
964    pub(crate) fn persisted_row_slot_lookup_out_of_bounds(_model_path: &str, _slot: usize) -> Self {
965        Self::index_invariant()
966    }
967
968    /// Construct the canonical persisted-row structural slot-cache invariant.
969    pub(crate) fn persisted_row_slot_cache_lookup_out_of_bounds(
970        _model_path: &str,
971        _slot: usize,
972    ) -> Self {
973        Self::index_invariant()
974    }
975
976    /// Construct the canonical persisted-row primary-key decode corruption error.
977    pub(crate) fn persisted_row_primary_key_not_primary_key_encodable(
978        _data_key: impl fmt::Debug,
979        _detail: impl Sized,
980    ) -> Self {
981        Self::persisted_row_decode_corruption()
982    }
983
984    /// Construct the canonical persisted-row missing primary-key slot corruption error.
985    pub(crate) fn persisted_row_primary_key_slot_missing(_data_key: impl fmt::Debug) -> Self {
986        Self::persisted_row_decode_corruption()
987    }
988
989    /// Construct the canonical persisted-row key mismatch corruption error.
990    pub(crate) fn persisted_row_key_mismatch() -> Self {
991        Self::store_corruption()
992    }
993
994    /// Construct the canonical persisted-row missing declared-field corruption error.
995    pub(crate) fn persisted_row_declared_field_missing(field_name: &str) -> Self {
996        Self::persisted_row_field_decode_corruption(field_name)
997    }
998
999    /// Construct the canonical data-key entity mismatch corruption error.
1000    pub(crate) fn data_key_entity_mismatch() -> Self {
1001        Self::store_corruption()
1002    }
1003
1004    /// Construct the canonical reverse-index ordinal overflow internal error.
1005    pub(crate) fn reverse_index_ordinal_overflow(
1006        _source_path: &str,
1007        _field_name: &str,
1008        _target_path: &str,
1009        _detail: impl Sized,
1010    ) -> Self {
1011        Self::index_internal()
1012    }
1013
1014    /// Construct the canonical reverse-index entry corruption error.
1015    pub(crate) fn reverse_index_entry_corrupted(
1016        _source_path: &str,
1017        _field_name: &str,
1018        _target_path: &str,
1019        _index_key: impl fmt::Debug,
1020        _detail: impl Sized,
1021    ) -> Self {
1022        Self::index_corruption()
1023    }
1024
1025    /// Construct the canonical relation-target store missing internal error.
1026    pub(crate) fn relation_target_store_missing(
1027        _source_path: &str,
1028        _field_name: &str,
1029        _target_path: &str,
1030        _store_path: &str,
1031        _detail: impl Sized,
1032    ) -> Self {
1033        Self::executor_internal()
1034    }
1035
1036    /// Construct the canonical relation-target key decode corruption error.
1037    pub(crate) fn relation_target_key_decode_failed(
1038        _context_label: &str,
1039        _source_path: &str,
1040        _field_name: &str,
1041        _target_path: &str,
1042        _detail: impl Sized,
1043    ) -> Self {
1044        Self::identity_corruption()
1045    }
1046
1047    /// Construct the canonical relation-target entity mismatch corruption error.
1048    pub(crate) fn relation_target_entity_mismatch(
1049        _context_label: &str,
1050        _source_path: &str,
1051        _field_name: &str,
1052        _target_path: &str,
1053        _target_entity_name: &str,
1054        _expected_tag: impl Sized,
1055        _actual_tag: impl Sized,
1056    ) -> Self {
1057        Self::store_corruption()
1058    }
1059
1060    /// Construct the canonical relation-source row decode corruption error.
1061    pub(crate) fn relation_source_row_decode_failed(
1062        _source_path: &str,
1063        _field_name: &str,
1064        _target_path: &str,
1065        _detail: impl Sized,
1066    ) -> Self {
1067        Self::persisted_row_decode_corruption()
1068    }
1069
1070    /// Construct the canonical relation-source unsupported scalar relation-key corruption error.
1071    pub(crate) fn relation_source_row_unsupported_scalar_relation_key(
1072        _source_path: &str,
1073        _field_name: &str,
1074        _target_path: &str,
1075    ) -> Self {
1076        Self::persisted_row_decode_corruption()
1077    }
1078
1079    /// Construct the canonical unsupported relation key-kind corruption error.
1080    pub(crate) fn relation_source_row_unsupported_key_kind(_field_kind: impl fmt::Debug) -> Self {
1081        Self::persisted_row_decode_corruption()
1082    }
1083
1084    /// Construct the canonical reverse-index relation-target decode invariant failure.
1085    pub(crate) fn reverse_index_relation_target_decode_invariant_violated(
1086        _source_path: &str,
1087        _field_name: &str,
1088        _target_path: &str,
1089    ) -> Self {
1090        Self::executor_internal()
1091    }
1092
1093    /// Construct the canonical covering-component empty-payload corruption error.
1094    pub(crate) fn bytes_covering_component_payload_empty() -> Self {
1095        Self::index_corruption()
1096    }
1097
1098    /// Construct the canonical covering-component truncated bool corruption error.
1099    pub(crate) fn bytes_covering_bool_payload_truncated() -> Self {
1100        Self::index_corruption()
1101    }
1102
1103    /// Construct the canonical covering-component invalid-length corruption error.
1104    pub(crate) fn bytes_covering_component_payload_invalid_length() -> Self {
1105        Self::index_corruption()
1106    }
1107
1108    /// Construct the canonical covering-component invalid-bool corruption error.
1109    pub(crate) fn bytes_covering_bool_payload_invalid_value() -> Self {
1110        Self::index_corruption()
1111    }
1112
1113    /// Construct the canonical covering-component invalid text terminator corruption error.
1114    pub(crate) fn bytes_covering_text_payload_invalid_terminator() -> Self {
1115        Self::index_corruption()
1116    }
1117
1118    /// Construct the canonical covering-component trailing-text corruption error.
1119    pub(crate) fn bytes_covering_text_payload_trailing_bytes() -> Self {
1120        Self::index_corruption()
1121    }
1122
1123    /// Construct the canonical covering-component invalid-UTF-8 text corruption error.
1124    pub(crate) fn bytes_covering_text_payload_invalid_utf8() -> Self {
1125        Self::index_corruption()
1126    }
1127
1128    /// Construct the canonical covering-component invalid text escape corruption error.
1129    pub(crate) fn bytes_covering_text_payload_invalid_escape_byte() -> Self {
1130        Self::index_corruption()
1131    }
1132
1133    /// Construct the canonical covering-component missing text terminator corruption error.
1134    pub(crate) fn bytes_covering_text_payload_missing_terminator() -> Self {
1135        Self::index_corruption()
1136    }
1137
1138    /// Construct the canonical missing persisted-field decode error.
1139    #[must_use]
1140    pub fn missing_persisted_slot(field_name: &'static str) -> Self {
1141        Self::persisted_row_field_decode_corruption(field_name)
1142    }
1143
1144    /// Construct an identity-origin corruption error.
1145    pub(crate) fn identity_corruption() -> Self {
1146        Self::new(ErrorClass::Corruption, ErrorOrigin::Identity)
1147    }
1148
1149    /// Construct a store-origin unsupported error.
1150    #[cold]
1151    #[inline(never)]
1152    pub(crate) fn store_unsupported() -> Self {
1153        Self::new(ErrorClass::Unsupported, ErrorOrigin::Store)
1154    }
1155
1156    /// Construct the canonical schema DDL publication race error.
1157    #[cfg(any(test, feature = "sql"))]
1158    pub(crate) fn schema_ddl_publication_race_lost(_entity_path: &'static str) -> Self {
1159        Self {
1160            class: ErrorClass::Unsupported,
1161            origin: ErrorOrigin::Store,
1162            detail: Some(ErrorDetail::Store(StoreError::SchemaDdlPublicationRaceLost)),
1163        }
1164    }
1165
1166    /// Construct the canonical SQL DDL SET NOT NULL validation failure.
1167    #[cfg(feature = "sql")]
1168    pub(crate) fn schema_ddl_set_not_null_validation_failed(
1169        _entity_path: &'static str,
1170        _column_name: &str,
1171    ) -> Self {
1172        Self {
1173            class: ErrorClass::Unsupported,
1174            origin: ErrorOrigin::Store,
1175            detail: Some(ErrorDetail::Store(
1176                StoreError::SchemaDdlSetNotNullValidationFailed,
1177            )),
1178        }
1179    }
1180
1181    /// Construct the canonical unsupported persisted entity-tag store error.
1182    pub(crate) fn unsupported_entity_tag_in_data_store(
1183        _entity_tag: crate::types::EntityTag,
1184    ) -> Self {
1185        Self::store_unsupported()
1186    }
1187
1188    /// Construct the canonical commit-memory id registration failure.
1189    #[cfg(not(test))]
1190    pub(crate) fn commit_memory_id_registration_failed(_err: impl Sized) -> Self {
1191        Self::store_internal()
1192    }
1193
1194    /// Construct an index-origin unsupported error.
1195    pub(crate) fn index_unsupported() -> Self {
1196        Self::new(ErrorClass::Unsupported, ErrorOrigin::Index)
1197    }
1198
1199    /// Construct the canonical index-key component size-limit unsupported error.
1200    pub(crate) fn index_component_exceeds_max_size() -> Self {
1201        Self::index_unsupported()
1202    }
1203
1204    /// Construct a serialize-origin unsupported error.
1205    pub(crate) fn serialize_unsupported() -> Self {
1206        Self::new(ErrorClass::Unsupported, ErrorOrigin::Serialize)
1207    }
1208
1209    /// Construct a cursor-origin invalid-continuation error.
1210    pub(crate) fn cursor_invalid_continuation() -> Self {
1211        Self::new(ErrorClass::Unsupported, ErrorOrigin::Cursor)
1212    }
1213
1214    /// Construct a serialize-origin incompatible persisted-format error.
1215    pub(crate) fn serialize_incompatible_persisted_format() -> Self {
1216        Self::new(
1217            ErrorClass::IncompatiblePersistedFormat,
1218            ErrorOrigin::Serialize,
1219        )
1220    }
1221
1222    /// Construct a query-origin unsupported error preserving one SQL parser
1223    /// unsupported-feature code in structured error detail.
1224    #[cfg(feature = "sql")]
1225    pub(crate) fn query_unsupported_sql_feature(feature: diagnostic_code::SqlFeatureCode) -> Self {
1226        Self {
1227            class: ErrorClass::Unsupported,
1228            origin: ErrorOrigin::Query,
1229            detail: Some(ErrorDetail::Query(
1230                QueryErrorDetail::UnsupportedSqlFeature { feature },
1231            )),
1232        }
1233    }
1234
1235    /// Construct a query-origin unsupported SQL lowering error preserving one
1236    /// compact lowering reason in structured error detail.
1237    #[cfg(feature = "sql")]
1238    pub(crate) fn query_sql_lowering(reason: diagnostic_code::SqlLoweringCode) -> Self {
1239        Self {
1240            class: ErrorClass::Unsupported,
1241            origin: ErrorOrigin::Query,
1242            detail: Some(ErrorDetail::Query(QueryErrorDetail::SqlLowering { reason })),
1243        }
1244    }
1245
1246    /// Construct a query-origin unsupported projection error preserving one
1247    /// compact projection reason in structured error detail.
1248    pub(crate) fn query_unsupported_projection(
1249        reason: diagnostic_code::QueryProjectionCode,
1250    ) -> Self {
1251        Self {
1252            class: ErrorClass::Unsupported,
1253            origin: ErrorOrigin::Query,
1254            detail: Some(ErrorDetail::Query(
1255                QueryErrorDetail::UnsupportedProjection { reason },
1256            )),
1257        }
1258    }
1259
1260    /// Construct a query-origin unsupported aggregate target-field error.
1261    pub(crate) fn query_unknown_aggregate_target_field() -> Self {
1262        Self {
1263            class: ErrorClass::Unsupported,
1264            origin: ErrorOrigin::Query,
1265            detail: Some(ErrorDetail::Query(
1266                QueryErrorDetail::UnknownAggregateTargetField,
1267            )),
1268        }
1269    }
1270
1271    /// Construct a query-origin result-shape mismatch error preserving one
1272    /// compact result-shape reason in structured error detail.
1273    pub(crate) fn query_result_shape_mismatch(
1274        reason: diagnostic_code::QueryResultShapeCode,
1275    ) -> Self {
1276        Self {
1277            class: ErrorClass::Unsupported,
1278            origin: ErrorOrigin::Query,
1279            detail: Some(ErrorDetail::Query(QueryErrorDetail::ResultShapeMismatch {
1280                reason,
1281            })),
1282        }
1283    }
1284
1285    /// Construct a query-origin unsupported error preserving one SQL endpoint
1286    /// surface mismatch in structured error detail.
1287    #[cfg(feature = "sql")]
1288    pub(crate) fn query_sql_surface_mismatch(
1289        mismatch: diagnostic_code::SqlSurfaceMismatchCode,
1290    ) -> Self {
1291        Self {
1292            class: ErrorClass::Unsupported,
1293            origin: ErrorOrigin::Query,
1294            detail: Some(ErrorDetail::Query(QueryErrorDetail::SqlSurfaceMismatch {
1295                mismatch,
1296            })),
1297        }
1298    }
1299
1300    /// Construct a query-origin unsupported SQL write boundary error.
1301    #[cfg(feature = "sql")]
1302    pub(crate) fn query_sql_write_boundary(
1303        boundary: diagnostic_code::SqlWriteBoundaryCode,
1304    ) -> Self {
1305        Self {
1306            class: ErrorClass::Unsupported,
1307            origin: ErrorOrigin::Query,
1308            detail: Some(ErrorDetail::Query(QueryErrorDetail::SqlWriteBoundary {
1309                boundary,
1310            })),
1311        }
1312    }
1313
1314    pub fn store_not_found(_key: impl Sized) -> Self {
1315        Self {
1316            class: ErrorClass::NotFound,
1317            origin: ErrorOrigin::Store,
1318            detail: Some(ErrorDetail::Store(StoreError::NotFound)),
1319        }
1320    }
1321
1322    /// Construct a standardized unsupported-entity-path error.
1323    pub fn unsupported_entity_path(_path: impl Sized) -> Self {
1324        Self::store_unsupported()
1325    }
1326
1327    #[must_use]
1328    pub const fn is_not_found(&self) -> bool {
1329        matches!(self.detail, Some(ErrorDetail::Store(StoreError::NotFound)))
1330    }
1331
1332    /// Construct an index-plan corruption error with a canonical prefix.
1333    #[cold]
1334    #[inline(never)]
1335    pub(crate) fn index_plan_corruption(origin: ErrorOrigin) -> Self {
1336        Self::new(ErrorClass::Corruption, origin)
1337    }
1338
1339    /// Construct an index-plan corruption error for index-origin failures.
1340    #[cold]
1341    #[inline(never)]
1342    pub(crate) fn index_plan_index_corruption() -> Self {
1343        Self::index_plan_corruption(ErrorOrigin::Index)
1344    }
1345
1346    /// Construct an index-plan corruption error for store-origin failures.
1347    #[cold]
1348    #[inline(never)]
1349    pub(crate) fn index_plan_store_corruption() -> Self {
1350        Self::index_plan_corruption(ErrorOrigin::Store)
1351    }
1352
1353    /// Construct an index-plan corruption error for serialize-origin failures.
1354    #[cold]
1355    #[inline(never)]
1356    pub(crate) fn index_plan_serialize_corruption() -> Self {
1357        Self::index_plan_corruption(ErrorOrigin::Serialize)
1358    }
1359
1360    /// Construct an index-plan invariant violation error with a canonical prefix.
1361    #[cfg(test)]
1362    pub(crate) fn index_plan_invariant(origin: ErrorOrigin) -> Self {
1363        Self::new(ErrorClass::InvariantViolation, origin)
1364    }
1365
1366    /// Construct an index-plan invariant violation error for store-origin failures.
1367    #[cfg(test)]
1368    pub(crate) fn index_plan_store_invariant() -> Self {
1369        Self::index_plan_invariant(ErrorOrigin::Store)
1370    }
1371
1372    /// Construct an index uniqueness violation conflict error.
1373    pub(crate) fn index_violation(_path: &str, _index_fields: &[&str]) -> Self {
1374        Self::new(ErrorClass::Conflict, ErrorOrigin::Index)
1375    }
1376}
1377
1378impl From<diagnostic_code::QueryReadAdmissionCode> for InternalError {
1379    fn from(reason: diagnostic_code::QueryReadAdmissionCode) -> Self {
1380        Self {
1381            class: ErrorClass::Unsupported,
1382            origin: ErrorOrigin::Query,
1383            detail: Some(ErrorDetail::Query(QueryErrorDetail::QueryReadAdmission {
1384                reason,
1385            })),
1386        }
1387    }
1388}
1389
1390impl fmt::Debug for InternalError {
1391    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1392        fmt_compact_diagnostic(
1393            f,
1394            self.diagnostic_code(),
1395            self.detail
1396                .as_ref()
1397                .and_then(ErrorDetail::diagnostic_detail),
1398        )
1399    }
1400}
1401
1402impl fmt::Display for InternalError {
1403    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1404        f.write_str(self.message())
1405    }
1406}
1407
1408impl std::error::Error for InternalError {}
1409
1410///
1411/// ErrorDetail
1412///
1413/// Structured, origin-specific error detail carried by [`InternalError`].
1414/// This enum is intentionally extensible.
1415///
1416
1417pub enum ErrorDetail {
1418    Store(StoreError),
1419    Query(QueryErrorDetail),
1420    Recovery(RecoveryErrorDetail),
1421    // Future-proofing:
1422    // Index(IndexError),
1423    //
1424    // Executor(ExecutorErrorDetail),
1425}
1426
1427///
1428/// RecoveryErrorDetail
1429///
1430/// Recovery-origin structured error detail payload.
1431///
1432
1433pub enum RecoveryErrorDetail {
1434    UnsupportedFormatVersion { found: Option<u16>, required: u16 },
1435
1436    MalformedFormatMarker { reason: RecoveryFormatMarkerError },
1437}
1438
1439/// Store boot-marker corruption classification.
1440#[derive(Clone, Copy, Eq, PartialEq)]
1441pub enum RecoveryFormatMarkerError {
1442    Magic,
1443    Checksum,
1444    State,
1445}
1446
1447///
1448/// StoreError
1449///
1450/// Store-specific structured error detail.
1451/// Never returned directly; always wrapped in [`ErrorDetail::Store`].
1452///
1453
1454pub enum StoreError {
1455    NotFound,
1456
1457    Corrupt,
1458
1459    InvariantViolation,
1460
1461    SchemaDdlPublicationRaceLost,
1462
1463    SchemaDdlSetNotNullValidationFailed,
1464}
1465
1466///
1467/// QueryErrorDetail
1468///
1469/// Query-origin structured error detail payload.
1470///
1471
1472pub enum QueryErrorDetail {
1473    NumericOverflow,
1474
1475    NumericNotRepresentable,
1476
1477    UnsupportedSqlFeature {
1478        feature: diagnostic_code::SqlFeatureCode,
1479    },
1480
1481    SqlLowering {
1482        reason: diagnostic_code::SqlLoweringCode,
1483    },
1484
1485    UnsupportedProjection {
1486        reason: diagnostic_code::QueryProjectionCode,
1487    },
1488
1489    UnknownAggregateTargetField,
1490
1491    ResultShapeMismatch {
1492        reason: diagnostic_code::QueryResultShapeCode,
1493    },
1494
1495    QueryReadAdmission {
1496        reason: diagnostic_code::QueryReadAdmissionCode,
1497    },
1498
1499    SqlSurfaceMismatch {
1500        mismatch: diagnostic_code::SqlSurfaceMismatchCode,
1501    },
1502
1503    SqlWriteBoundary {
1504        boundary: diagnostic_code::SqlWriteBoundaryCode,
1505    },
1506
1507    SchemaDdlAdmission {
1508        error: SchemaDdlAdmissionError,
1509    },
1510
1511    StaleSchemaRevision,
1512}
1513
1514impl fmt::Display for QueryErrorDetail {
1515    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1516        f.write_str(COMPACT_QUERY_DIAGNOSTIC_MESSAGE)
1517    }
1518}
1519
1520impl std::error::Error for QueryErrorDetail {}
1521
1522///
1523/// SchemaDdlAdmissionError
1524///
1525/// Stable query-visible SQL DDL admission reason. Human diagnostics may carry
1526/// extra version, fingerprint, and target facts beside this machine-readable
1527/// variant.
1528///
1529
1530#[derive(Clone, Copy, Eq, PartialEq)]
1531pub enum SchemaDdlAdmissionError {
1532    MissingExpectedSchemaVersion,
1533
1534    MissingNextSchemaVersion,
1535
1536    StaleExpectedSchemaVersion,
1537
1538    InvalidExpectedSchemaVersion,
1539
1540    InvalidNextSchemaVersion,
1541
1542    AcceptedSchemaChangeWithoutVersionBump,
1543
1544    EmptyVersionBump,
1545
1546    VersionGap,
1547
1548    VersionRollback,
1549
1550    FingerprintMethodMismatch,
1551
1552    UnsupportedTransitionClass,
1553
1554    PhysicalRunnerMissing,
1555
1556    ValidationFailed,
1557
1558    PublicationRaceLost,
1559
1560    InvalidAddColumnDefault,
1561
1562    InvalidAlterColumnDefault,
1563
1564    GeneratedIndexDropRejected,
1565
1566    RequiredDropDefaultUnsupported,
1567
1568    GeneratedFieldDefaultChangeRejected,
1569
1570    GeneratedFieldNullabilityChangeRejected,
1571
1572    SetNotNullValidationFailed,
1573}
1574
1575impl fmt::Display for SchemaDdlAdmissionError {
1576    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1577        f.write_str(COMPACT_QUERY_DIAGNOSTIC_MESSAGE)
1578    }
1579}
1580
1581impl std::error::Error for SchemaDdlAdmissionError {}
1582
1583impl fmt::Debug for ErrorDetail {
1584    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1585        fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
1586    }
1587}
1588
1589impl fmt::Debug for StoreError {
1590    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1591        fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
1592    }
1593}
1594
1595impl fmt::Debug for QueryErrorDetail {
1596    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1597        fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
1598    }
1599}
1600
1601impl fmt::Debug for RecoveryErrorDetail {
1602    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1603        fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
1604    }
1605}
1606
1607impl fmt::Debug for RecoveryFormatMarkerError {
1608    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1609        fmt_compact_diagnostic(
1610            f,
1611            diagnostic_code::DiagnosticCode::RuntimeCorruption,
1612            Some(diagnostic_code::DiagnosticDetail::RuntimeKind {
1613                kind: diagnostic_code::RuntimeErrorKind::Corruption,
1614            }),
1615        )
1616    }
1617}
1618
1619impl fmt::Debug for SchemaDdlAdmissionError {
1620    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1621        fmt_compact_diagnostic(
1622            f,
1623            diagnostic_code::DiagnosticCode::SchemaDdlAdmission,
1624            Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
1625                reason: self.diagnostic_code(),
1626            }),
1627        )
1628    }
1629}
1630
1631fn fmt_compact_diagnostic(
1632    f: &mut fmt::Formatter<'_>,
1633    code: diagnostic_code::DiagnosticCode,
1634    detail: Option<diagnostic_code::DiagnosticDetail>,
1635) -> fmt::Result {
1636    write!(
1637        f,
1638        "{}",
1639        diagnostic_code::ErrorCode::from_parts(code, detail).raw()
1640    )
1641}
1642
1643impl ErrorDetail {
1644    /// Return the compact diagnostic code for this structured detail.
1645    #[must_use]
1646    pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
1647        match self {
1648            Self::Store(error) => error.diagnostic_code(),
1649            Self::Query(error) => error.diagnostic_code(),
1650            Self::Recovery(error) => error.diagnostic_code(),
1651        }
1652    }
1653
1654    /// Return compact structured diagnostic detail when the payload carries one.
1655    #[must_use]
1656    pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
1657        match self {
1658            Self::Store(error) => error.diagnostic_detail(),
1659            Self::Query(error) => error.diagnostic_detail(),
1660            Self::Recovery(error) => error.diagnostic_detail(),
1661        }
1662    }
1663}
1664
1665impl RecoveryErrorDetail {
1666    /// Return the compact diagnostic code for this recovery detail.
1667    #[must_use]
1668    pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
1669        match self {
1670            Self::UnsupportedFormatVersion { .. } => {
1671                diagnostic_code::DiagnosticCode::RuntimeIncompatiblePersistedFormat
1672            }
1673            Self::MalformedFormatMarker { .. } => {
1674                diagnostic_code::DiagnosticCode::RuntimeCorruption
1675            }
1676        }
1677    }
1678
1679    /// Return compact structured diagnostic detail for this recovery detail.
1680    #[must_use]
1681    pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
1682        let kind = match self {
1683            Self::UnsupportedFormatVersion { .. } => {
1684                diagnostic_code::RuntimeErrorKind::IncompatiblePersistedFormat
1685            }
1686            Self::MalformedFormatMarker { .. } => diagnostic_code::RuntimeErrorKind::Corruption,
1687        };
1688
1689        Some(diagnostic_code::DiagnosticDetail::RuntimeKind { kind })
1690    }
1691}
1692
1693impl StoreError {
1694    /// Return the compact diagnostic code for this store detail.
1695    #[must_use]
1696    pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
1697        match self {
1698            Self::NotFound => diagnostic_code::DiagnosticCode::StoreNotFound,
1699            Self::Corrupt => diagnostic_code::DiagnosticCode::StoreCorruption,
1700            Self::InvariantViolation => diagnostic_code::DiagnosticCode::StoreInvariantViolation,
1701            Self::SchemaDdlPublicationRaceLost | Self::SchemaDdlSetNotNullValidationFailed => {
1702                diagnostic_code::DiagnosticCode::SchemaDdlAdmission
1703            }
1704        }
1705    }
1706
1707    /// Return compact structured diagnostic detail when the store error has one.
1708    #[must_use]
1709    pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
1710        match self {
1711            Self::SchemaDdlPublicationRaceLost => {
1712                Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
1713                    reason: diagnostic_code::SchemaDdlAdmissionCode::PublicationRaceLost,
1714                })
1715            }
1716            Self::SchemaDdlSetNotNullValidationFailed => {
1717                Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
1718                    reason: diagnostic_code::SchemaDdlAdmissionCode::SetNotNullValidationFailed,
1719                })
1720            }
1721            Self::NotFound | Self::Corrupt | Self::InvariantViolation => None,
1722        }
1723    }
1724}
1725
1726impl QueryErrorDetail {
1727    /// Return the compact diagnostic code for this query detail.
1728    #[must_use]
1729    pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
1730        match self {
1731            Self::NumericOverflow => diagnostic_code::DiagnosticCode::QueryNumericOverflow,
1732            Self::NumericNotRepresentable => {
1733                diagnostic_code::DiagnosticCode::QueryNumericNotRepresentable
1734            }
1735            Self::UnsupportedSqlFeature { .. } => {
1736                diagnostic_code::DiagnosticCode::QueryUnsupportedSqlFeature
1737            }
1738            Self::SqlLowering { .. } => diagnostic_code::DiagnosticCode::QueryUnsupportedSqlFeature,
1739            Self::UnsupportedProjection { .. } => {
1740                diagnostic_code::DiagnosticCode::QueryUnsupportedProjection
1741            }
1742            Self::UnknownAggregateTargetField => {
1743                diagnostic_code::DiagnosticCode::QueryUnknownAggregateTargetField
1744            }
1745            Self::ResultShapeMismatch { .. } => {
1746                diagnostic_code::DiagnosticCode::QueryResultShapeMismatch
1747            }
1748            Self::QueryReadAdmission { .. } => diagnostic_code::DiagnosticCode::QueryReadAdmission,
1749            Self::SqlSurfaceMismatch { .. } => {
1750                diagnostic_code::DiagnosticCode::QuerySqlSurfaceMismatch
1751            }
1752            Self::SqlWriteBoundary { .. } => diagnostic_code::DiagnosticCode::QuerySqlWriteBoundary,
1753            Self::SchemaDdlAdmission { .. } => diagnostic_code::DiagnosticCode::SchemaDdlAdmission,
1754            Self::StaleSchemaRevision => diagnostic_code::DiagnosticCode::RuntimeConflict,
1755        }
1756    }
1757
1758    /// Return compact structured diagnostic detail when the query detail has one.
1759    #[must_use]
1760    pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
1761        match self {
1762            Self::UnsupportedSqlFeature { feature } => {
1763                Some(diagnostic_code::DiagnosticDetail::UnsupportedSqlFeature { feature: *feature })
1764            }
1765            Self::SqlLowering { reason } => {
1766                Some(diagnostic_code::DiagnosticDetail::SqlLowering { reason: *reason })
1767            }
1768            Self::UnsupportedProjection { reason } => {
1769                Some(diagnostic_code::DiagnosticDetail::QueryProjection { reason: *reason })
1770            }
1771            Self::ResultShapeMismatch { reason } => {
1772                Some(diagnostic_code::DiagnosticDetail::QueryResultShape { reason: *reason })
1773            }
1774            Self::QueryReadAdmission { reason } => {
1775                Some(diagnostic_code::DiagnosticDetail::QueryReadAdmission { reason: *reason })
1776            }
1777            Self::SqlSurfaceMismatch { mismatch } => {
1778                Some(diagnostic_code::DiagnosticDetail::SqlSurfaceMismatch {
1779                    mismatch: *mismatch,
1780                })
1781            }
1782            Self::SqlWriteBoundary { boundary } => {
1783                Some(diagnostic_code::DiagnosticDetail::SqlWriteBoundary {
1784                    boundary: *boundary,
1785                })
1786            }
1787            Self::SchemaDdlAdmission { error } => {
1788                Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
1789                    reason: error.diagnostic_code(),
1790                })
1791            }
1792            Self::NumericOverflow
1793            | Self::NumericNotRepresentable
1794            | Self::UnknownAggregateTargetField
1795            | Self::StaleSchemaRevision => None,
1796        }
1797    }
1798}
1799
1800impl SchemaDdlAdmissionError {
1801    /// Return the compact diagnostic code for this SQL DDL admission reason.
1802    #[must_use]
1803    pub const fn diagnostic_code(&self) -> diagnostic_code::SchemaDdlAdmissionCode {
1804        match self {
1805            Self::MissingExpectedSchemaVersion => {
1806                diagnostic_code::SchemaDdlAdmissionCode::MissingExpectedSchemaVersion
1807            }
1808            Self::MissingNextSchemaVersion => {
1809                diagnostic_code::SchemaDdlAdmissionCode::MissingNextSchemaVersion
1810            }
1811            Self::StaleExpectedSchemaVersion => {
1812                diagnostic_code::SchemaDdlAdmissionCode::StaleExpectedSchemaVersion
1813            }
1814            Self::InvalidExpectedSchemaVersion => {
1815                diagnostic_code::SchemaDdlAdmissionCode::InvalidExpectedSchemaVersion
1816            }
1817            Self::InvalidNextSchemaVersion => {
1818                diagnostic_code::SchemaDdlAdmissionCode::InvalidNextSchemaVersion
1819            }
1820            Self::AcceptedSchemaChangeWithoutVersionBump => {
1821                diagnostic_code::SchemaDdlAdmissionCode::AcceptedSchemaChangeWithoutVersionBump
1822            }
1823            Self::EmptyVersionBump => diagnostic_code::SchemaDdlAdmissionCode::EmptyVersionBump,
1824            Self::VersionGap => diagnostic_code::SchemaDdlAdmissionCode::VersionGap,
1825            Self::VersionRollback => diagnostic_code::SchemaDdlAdmissionCode::VersionRollback,
1826            Self::FingerprintMethodMismatch => {
1827                diagnostic_code::SchemaDdlAdmissionCode::FingerprintMethodMismatch
1828            }
1829            Self::UnsupportedTransitionClass => {
1830                diagnostic_code::SchemaDdlAdmissionCode::UnsupportedTransitionClass
1831            }
1832            Self::PhysicalRunnerMissing => {
1833                diagnostic_code::SchemaDdlAdmissionCode::PhysicalRunnerMissing
1834            }
1835            Self::ValidationFailed => diagnostic_code::SchemaDdlAdmissionCode::ValidationFailed,
1836            Self::PublicationRaceLost => {
1837                diagnostic_code::SchemaDdlAdmissionCode::PublicationRaceLost
1838            }
1839            Self::InvalidAddColumnDefault => {
1840                diagnostic_code::SchemaDdlAdmissionCode::InvalidAddColumnDefault
1841            }
1842            Self::InvalidAlterColumnDefault => {
1843                diagnostic_code::SchemaDdlAdmissionCode::InvalidAlterColumnDefault
1844            }
1845            Self::GeneratedIndexDropRejected => {
1846                diagnostic_code::SchemaDdlAdmissionCode::GeneratedIndexDropRejected
1847            }
1848            Self::RequiredDropDefaultUnsupported => {
1849                diagnostic_code::SchemaDdlAdmissionCode::RequiredDropDefaultUnsupported
1850            }
1851            Self::GeneratedFieldDefaultChangeRejected => {
1852                diagnostic_code::SchemaDdlAdmissionCode::GeneratedFieldDefaultChangeRejected
1853            }
1854            Self::GeneratedFieldNullabilityChangeRejected => {
1855                diagnostic_code::SchemaDdlAdmissionCode::GeneratedFieldNullabilityChangeRejected
1856            }
1857            Self::SetNotNullValidationFailed => {
1858                diagnostic_code::SchemaDdlAdmissionCode::SetNotNullValidationFailed
1859            }
1860        }
1861    }
1862}
1863
1864///
1865/// ErrorClass
1866/// Internal error taxonomy for runtime classification.
1867/// Not a stable API; may change without notice.
1868///
1869
1870#[repr(u16)]
1871#[derive(Clone, Copy, Eq, PartialEq)]
1872pub enum ErrorClass {
1873    Corruption,
1874    IncompatiblePersistedFormat,
1875    NotFound,
1876    Internal,
1877    Conflict,
1878    Unsupported,
1879    InvariantViolation,
1880}
1881
1882impl ErrorClass {
1883    /// Return a compact diagnostic code for this broad class and origin pair.
1884    #[must_use]
1885    pub const fn diagnostic_code(self, origin: ErrorOrigin) -> diagnostic_code::DiagnosticCode {
1886        match self {
1887            Self::Corruption if matches!(origin, ErrorOrigin::Store) => {
1888                diagnostic_code::DiagnosticCode::StoreCorruption
1889            }
1890            Self::Corruption => diagnostic_code::DiagnosticCode::RuntimeCorruption,
1891            Self::IncompatiblePersistedFormat => {
1892                diagnostic_code::DiagnosticCode::RuntimeIncompatiblePersistedFormat
1893            }
1894            Self::NotFound if matches!(origin, ErrorOrigin::Store) => {
1895                diagnostic_code::DiagnosticCode::StoreNotFound
1896            }
1897            Self::NotFound => diagnostic_code::DiagnosticCode::RuntimeNotFound,
1898            Self::Internal => diagnostic_code::DiagnosticCode::RuntimeInternal,
1899            Self::Conflict => diagnostic_code::DiagnosticCode::RuntimeConflict,
1900            Self::Unsupported if matches!(origin, ErrorOrigin::Cursor) => {
1901                diagnostic_code::DiagnosticCode::QueryInvalidContinuationCursor
1902            }
1903            Self::Unsupported => diagnostic_code::DiagnosticCode::RuntimeUnsupported,
1904            Self::InvariantViolation if matches!(origin, ErrorOrigin::Store) => {
1905                diagnostic_code::DiagnosticCode::StoreInvariantViolation
1906            }
1907            Self::InvariantViolation => diagnostic_code::DiagnosticCode::RuntimeInvariantViolation,
1908        }
1909    }
1910}
1911
1912impl fmt::Debug for ErrorClass {
1913    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1914        write!(f, "{}", *self as u16)
1915    }
1916}
1917
1918///
1919/// ErrorOrigin
1920/// Internal origin taxonomy for runtime classification.
1921/// Not a stable API; may change without notice.
1922///
1923
1924#[repr(u16)]
1925#[derive(Clone, Copy, Eq, PartialEq)]
1926pub enum ErrorOrigin {
1927    Serialize,
1928    Store,
1929    Index,
1930    Identity,
1931    Query,
1932    Planner,
1933    Cursor,
1934    Recovery,
1935    Response,
1936    Executor,
1937    Interface,
1938}
1939
1940impl ErrorOrigin {
1941    /// Return the compact diagnostic origin for this internal origin.
1942    #[must_use]
1943    pub const fn diagnostic_origin(self) -> diagnostic_code::ErrorOrigin {
1944        match self {
1945            Self::Serialize => diagnostic_code::ErrorOrigin::Serialize,
1946            Self::Store => diagnostic_code::ErrorOrigin::Store,
1947            Self::Index => diagnostic_code::ErrorOrigin::Index,
1948            Self::Identity => diagnostic_code::ErrorOrigin::Identity,
1949            Self::Query => diagnostic_code::ErrorOrigin::Query,
1950            Self::Planner => diagnostic_code::ErrorOrigin::Planner,
1951            Self::Cursor => diagnostic_code::ErrorOrigin::Cursor,
1952            Self::Recovery => diagnostic_code::ErrorOrigin::Recovery,
1953            Self::Response => diagnostic_code::ErrorOrigin::Response,
1954            Self::Executor => diagnostic_code::ErrorOrigin::Executor,
1955            Self::Interface => diagnostic_code::ErrorOrigin::Interface,
1956        }
1957    }
1958}
1959
1960impl fmt::Debug for ErrorOrigin {
1961    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1962        write!(f, "{}", *self as u16)
1963    }
1964}