1#[cfg(test)]
9mod tests;
10
11use candid::CandidType;
12use icydb_diagnostic_code as diagnostic_code;
13use serde::Deserialize;
14use std::fmt;
15
16pub(crate) const COMPACT_QUERY_DIAGNOSTIC_MESSAGE: &str = "query diagnostic";
17const COMPACT_RUNTIME_DIAGNOSTIC_MESSAGE: &str = "runtime diagnostic";
18const COMPACT_STORE_DIAGNOSTIC_MESSAGE: &str = "store diagnostic";
19const COMPACT_INDEX_DIAGNOSTIC_MESSAGE: &str = "index diagnostic";
20const COMPACT_SERIALIZE_DIAGNOSTIC_MESSAGE: &str = "serialize diagnostic";
21const COMPACT_IDENTITY_DIAGNOSTIC_MESSAGE: &str = "identity diagnostic";
22
23const fn compact_message_for(_class: ErrorClass, origin: ErrorOrigin) -> &'static str {
24 match origin {
25 ErrorOrigin::Serialize => COMPACT_SERIALIZE_DIAGNOSTIC_MESSAGE,
26 ErrorOrigin::Store => COMPACT_STORE_DIAGNOSTIC_MESSAGE,
27 ErrorOrigin::Index => COMPACT_INDEX_DIAGNOSTIC_MESSAGE,
28 ErrorOrigin::Identity => COMPACT_IDENTITY_DIAGNOSTIC_MESSAGE,
29 ErrorOrigin::Query | ErrorOrigin::Planner | ErrorOrigin::Response => {
30 COMPACT_QUERY_DIAGNOSTIC_MESSAGE
31 }
32 ErrorOrigin::Cursor
33 | ErrorOrigin::Recovery
34 | ErrorOrigin::Executor
35 | ErrorOrigin::Interface => COMPACT_RUNTIME_DIAGNOSTIC_MESSAGE,
36 }
37}
38
39pub struct InternalError {
140 pub(crate) class: ErrorClass,
141 pub(crate) origin: ErrorOrigin,
142
143 pub(crate) detail: Option<ErrorDetail>,
146}
147
148#[expect(
149 clippy::missing_const_for_fn,
150 reason = "internal error constructors stay non-const so compact diagnostic construction does not force const churn across subsystem helper seams"
151)]
152impl InternalError {
153 #[must_use]
157 #[cold]
158 #[inline(never)]
159 pub fn new(class: ErrorClass, origin: ErrorOrigin) -> Self {
160 let detail = match (class, origin) {
161 (ErrorClass::Corruption, ErrorOrigin::Store) => {
162 Some(ErrorDetail::Store(StoreError::Corrupt))
163 }
164 (ErrorClass::InvariantViolation, ErrorOrigin::Store) => {
165 Some(ErrorDetail::Store(StoreError::InvariantViolation))
166 }
167 _ => None,
168 };
169
170 Self {
171 class,
172 origin,
173 detail,
174 }
175 }
176
177 #[must_use]
179 pub const fn class(&self) -> ErrorClass {
180 self.class
181 }
182
183 #[must_use]
185 pub const fn origin(&self) -> ErrorOrigin {
186 self.origin
187 }
188
189 #[must_use]
191 pub const fn message(&self) -> &'static str {
192 compact_message_for(self.class, self.origin)
193 }
194
195 #[must_use]
197 pub const fn detail(&self) -> Option<&ErrorDetail> {
198 self.detail.as_ref()
199 }
200
201 #[must_use]
203 pub fn constraint_diagnostic(&self) -> Option<&ConstraintDiagnostic> {
204 match self.detail.as_ref() {
205 Some(ErrorDetail::Executor(detail)) => detail.constraint_diagnostic(),
206 Some(
207 ErrorDetail::Store(_)
208 | ErrorDetail::Query(_)
209 | ErrorDetail::Recovery(_)
210 | ErrorDetail::Serialize(_),
211 )
212 | None => None,
213 }
214 }
215
216 #[must_use]
218 pub fn diagnostic(&self) -> diagnostic_code::Diagnostic {
219 diagnostic_code::Diagnostic::new(
220 self.diagnostic_code(),
221 self.origin.diagnostic_origin(),
222 self.detail
223 .as_ref()
224 .and_then(ErrorDetail::diagnostic_detail),
225 )
226 }
227
228 #[must_use]
230 pub fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
231 self.detail.as_ref().map_or_else(
232 || self.class.diagnostic_code(self.origin),
233 ErrorDetail::diagnostic_code,
234 )
235 }
236
237 #[must_use]
239 pub fn into_message(self) -> String {
240 self.message().to_string()
241 }
242
243 #[cold]
245 #[inline(never)]
246 pub(crate) fn classified(class: ErrorClass, origin: ErrorOrigin) -> Self {
247 Self::new(class, origin)
248 }
249
250 #[cold]
254 #[inline(never)]
255 pub(crate) fn with_origin(self, origin: ErrorOrigin) -> Self {
256 Self::classified(self.class, origin)
257 }
258
259 #[cold]
261 #[inline(never)]
262 pub(crate) fn index_invariant() -> Self {
263 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Index)
264 }
265
266 pub(crate) fn index_key_field_count_exceeds_max(
268 _index_name: &str,
269 _field_count: usize,
270 _max_fields: usize,
271 ) -> Self {
272 Self::index_invariant()
273 }
274
275 pub(crate) fn index_key_item_field_missing_on_entity_model(_field: &str) -> Self {
277 Self::index_invariant()
278 }
279
280 pub(crate) fn index_key_item_field_missing_on_lookup_row(_field: &str) -> Self {
282 Self::index_invariant()
283 }
284
285 pub(crate) fn index_expression_source_type_mismatch(
287 _index_name: &str,
288 _expression: impl Sized,
289 _expected: impl Sized,
290 _source_label: &str,
291 ) -> Self {
292 Self::index_invariant()
293 }
294
295 #[cold]
298 #[inline(never)]
299 pub(crate) fn planner_executor_invariant() -> Self {
300 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Planner)
301 }
302
303 #[cold]
306 #[inline(never)]
307 pub(crate) fn query_executor_invariant() -> Self {
308 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Query)
309 }
310
311 #[cold]
314 #[inline(never)]
315 pub(crate) fn cursor_executor_invariant() -> Self {
316 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Cursor)
317 }
318
319 #[cold]
321 #[inline(never)]
322 pub(crate) fn executor_invariant() -> Self {
323 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Executor)
324 }
325
326 #[cold]
328 #[inline(never)]
329 pub(crate) fn executor_conflict() -> Self {
330 Self::new(ErrorClass::Conflict, ErrorOrigin::Executor)
331 }
332
333 #[cold]
335 #[inline(never)]
336 pub(crate) fn executor_internal() -> Self {
337 Self::new(ErrorClass::Internal, ErrorOrigin::Executor)
338 }
339
340 #[cold]
342 #[inline(never)]
343 pub(crate) fn executor_unsupported() -> Self {
344 Self::new(ErrorClass::Unsupported, ErrorOrigin::Executor)
345 }
346
347 pub(crate) fn mutation_entity_primary_key_missing(
349 _entity_path: &str,
350 _field_name: &str,
351 ) -> Self {
352 Self::executor_invariant()
353 }
354
355 pub(crate) fn mutation_entity_primary_key_invalid_value(
357 _entity_path: &str,
358 _field_name: &str,
359 _value: &crate::value::Value,
360 ) -> Self {
361 Self::executor_invariant()
362 }
363
364 pub(crate) fn mutation_entity_primary_key_type_mismatch(
366 _entity_path: &str,
367 _field_name: &str,
368 _value: &crate::value::Value,
369 ) -> Self {
370 Self::executor_invariant()
371 }
372
373 pub(crate) fn mutation_entity_primary_key_mismatch(
375 _entity_path: &str,
376 _field_name: &str,
377 _field_value: &crate::value::Value,
378 _identity_key: &crate::value::Value,
379 ) -> Self {
380 Self::executor_invariant()
381 }
382
383 pub(crate) fn mutation_entity_field_missing(
385 _entity_path: &str,
386 _field_name: &str,
387 _indexed: bool,
388 ) -> Self {
389 Self::executor_invariant()
390 }
391
392 pub(crate) fn mutation_structural_patch_required_field_missing(
394 entity_path: &str,
395 field_name: &str,
396 ) -> Self {
397 Self::mutation_required_field_missing(entity_path, field_name)
398 }
399
400 pub(crate) fn mutation_entity_field_type_mismatch(
402 _entity_path: &str,
403 _field_name: &str,
404 _value: &crate::value::Value,
405 ) -> Self {
406 Self::executor_invariant()
407 }
408
409 pub(crate) fn mutation_database_owned_field_explicit(
411 _entity_path: &str,
412 _field_name: &str,
413 ) -> Self {
414 Self::executor_unsupported()
415 }
416
417 pub(crate) fn mutation_sanitizer_protected_field_changed(
419 _entity_path: &str,
420 _field_name: &str,
421 ) -> Self {
422 Self::executor_unsupported()
423 }
424
425 #[must_use]
427 pub fn mutation_required_field_missing(_entity_path: &str, _field_names: &str) -> Self {
428 Self {
429 class: ErrorClass::Unsupported,
430 origin: ErrorOrigin::Executor,
431 detail: Some(ErrorDetail::Executor(
432 ExecutorErrorDetail::MutationRequiredFieldMissing,
433 )),
434 }
435 }
436
437 pub(crate) fn mutation_constraint_violation(diagnostic: ConstraintDiagnostic) -> Self {
439 Self {
440 class: ErrorClass::InvariantViolation,
441 origin: ErrorOrigin::Executor,
442 detail: Some(ErrorDetail::Executor(
443 ExecutorErrorDetail::ConstraintViolation {
444 diagnostic: Box::new(diagnostic),
445 },
446 )),
447 }
448 }
449
450 pub(crate) fn accepted_row_constraint_program_corrupt() -> Self {
452 Self {
453 class: ErrorClass::Corruption,
454 origin: ErrorOrigin::Executor,
455 detail: Some(ErrorDetail::Executor(
456 ExecutorErrorDetail::AcceptedRowConstraintProgramCorrupt,
457 )),
458 }
459 }
460
461 pub(crate) fn mutation_constraint_activation_write_blocked(
463 diagnostic: ConstraintDiagnostic,
464 ) -> Self {
465 Self {
466 class: ErrorClass::Conflict,
467 origin: ErrorOrigin::Executor,
468 detail: Some(ErrorDetail::Executor(
469 ExecutorErrorDetail::ConstraintActivationWriteBlocked {
470 diagnostic: Box::new(diagnostic),
471 },
472 )),
473 }
474 }
475
476 pub(crate) fn mutation_structural_after_image_invalid(
481 _entity_path: &str,
482 _data_key: impl Sized,
483 _detail: impl Sized,
484 ) -> Self {
485 Self::executor_invariant()
486 }
487
488 pub(crate) fn mutation_structural_field_unknown(_entity_path: &str, _field_name: &str) -> Self {
490 Self::executor_invariant()
491 }
492
493 pub(crate) fn mutation_decimal_scale_mismatch(
495 _entity_path: &str,
496 _field_name: &str,
497 _expected_scale: impl Sized,
498 _actual_scale: impl Sized,
499 ) -> Self {
500 Self::executor_unsupported()
501 }
502
503 pub(crate) fn mutation_text_max_len_exceeded(
505 _entity_path: &str,
506 _field_name: &str,
507 _max_len: impl Sized,
508 _actual_len: impl Sized,
509 ) -> Self {
510 Self::executor_unsupported()
511 }
512
513 pub(crate) fn mutation_set_field_list_required(_entity_path: &str, _field_name: &str) -> Self {
515 Self::executor_invariant()
516 }
517
518 pub(crate) fn mutation_set_field_not_canonical(_entity_path: &str, _field_name: &str) -> Self {
520 Self::executor_invariant()
521 }
522
523 pub(crate) fn mutation_map_field_map_required(_entity_path: &str, _field_name: &str) -> Self {
525 Self::executor_invariant()
526 }
527
528 pub(crate) fn mutation_map_field_entries_invalid(
530 _entity_path: &str,
531 _field_name: &str,
532 _detail: impl Sized,
533 ) -> Self {
534 Self::executor_invariant()
535 }
536
537 pub(crate) fn mutation_map_field_entries_not_canonical(
539 _entity_path: &str,
540 _field_name: &str,
541 ) -> Self {
542 Self::executor_invariant()
543 }
544
545 pub(crate) fn scalar_page_cursor_boundary_order_required() -> Self {
547 Self::query_executor_invariant()
548 }
549
550 pub(crate) fn scalar_page_cursor_boundary_after_ordering_required() -> Self {
552 Self::query_executor_invariant()
553 }
554
555 pub(crate) fn scalar_page_pagination_after_ordering_required() -> Self {
557 Self::query_executor_invariant()
558 }
559
560 pub(crate) fn load_executor_load_plan_required() -> Self {
562 Self::query_executor_invariant()
563 }
564
565 pub(crate) fn delete_executor_grouped_unsupported() -> Self {
567 Self::executor_unsupported()
568 }
569
570 pub(crate) fn delete_executor_delete_plan_required() -> Self {
572 Self::query_executor_invariant()
573 }
574
575 pub(crate) fn aggregate_fold_mode_terminal_contract_required() -> Self {
577 Self::query_executor_invariant()
578 }
579
580 pub(crate) fn fast_stream_route_kind_request_match_required() -> Self {
582 Self::query_executor_invariant()
583 }
584
585 pub(crate) fn secondary_index_prefix_spec_required() -> Self {
587 Self::query_executor_invariant()
588 }
589
590 pub(crate) fn index_range_limit_spec_required() -> Self {
592 Self::query_executor_invariant()
593 }
594
595 pub(crate) fn mutation_atomic_save_duplicate_key(_entity_path: &str, _key: impl Sized) -> Self {
597 Self::executor_conflict()
598 }
599
600 pub(crate) fn mutation_index_store_generation_changed(
602 _expected_generation: u64,
603 _observed_generation: u64,
604 ) -> Self {
605 Self::executor_invariant()
606 }
607
608 #[cold]
610 #[inline(never)]
611 pub(crate) fn planner_invariant() -> Self {
612 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Planner)
613 }
614
615 pub(crate) fn query_invalid_logical_plan() -> Self {
617 Self::planner_invariant()
618 }
619
620 pub(crate) fn store_invariant() -> Self {
622 Self::new(ErrorClass::InvariantViolation, ErrorOrigin::Store)
623 }
624
625 pub(crate) fn duplicate_runtime_hooks_for_entity_tag(
627 _entity_tag: crate::types::EntityTag,
628 ) -> Self {
629 Self::store_invariant()
630 }
631
632 pub(crate) fn duplicate_runtime_hooks_for_entity_path(_entity_path: &str) -> Self {
634 Self::store_invariant()
635 }
636
637 #[cold]
639 #[inline(never)]
640 pub(crate) fn store_internal() -> Self {
641 Self::new(ErrorClass::Internal, ErrorOrigin::Store)
642 }
643
644 pub(crate) fn commit_memory_id_unconfigured() -> Self {
646 Self::store_internal()
647 }
648
649 pub(crate) fn commit_memory_id_mismatch(_cached_id: u8, _configured_id: u8) -> Self {
651 Self::store_internal()
652 }
653
654 pub(crate) fn commit_memory_stable_key_mismatch(
656 _cached_key: &str,
657 _configured_key: &str,
658 ) -> Self {
659 Self::store_internal()
660 }
661
662 pub(crate) fn database_incarnation_generation_failed() -> Self {
664 Self::store_internal()
665 }
666
667 pub(crate) fn database_incarnation_invalid() -> Self {
669 Self::store_corruption()
670 }
671
672 pub(crate) fn recovery_unsupported_database_format(found: Option<u16>, required: u16) -> Self {
674 Self {
675 class: ErrorClass::IncompatiblePersistedFormat,
676 origin: ErrorOrigin::Recovery,
677 detail: Some(ErrorDetail::Recovery(
678 RecoveryErrorDetail::UnsupportedFormatVersion { found, required },
679 )),
680 }
681 }
682
683 pub(crate) fn recovery_malformed_database_format_marker(
685 reason: RecoveryFormatMarkerError,
686 ) -> Self {
687 Self {
688 class: ErrorClass::Corruption,
689 origin: ErrorOrigin::Recovery,
690 detail: Some(ErrorDetail::Recovery(
691 RecoveryErrorDetail::MalformedFormatMarker { reason },
692 )),
693 }
694 }
695
696 pub(crate) fn recovery_database_format_control_unavailable() -> Self {
698 Self::new(ErrorClass::Internal, ErrorOrigin::Recovery)
699 }
700
701 pub(crate) fn commit_control_memory_growth_failed() -> Self {
703 Self::store_internal()
704 }
705
706 #[cfg(not(test))]
708 pub(crate) fn database_format_memory_registration_failed(_err: impl Sized) -> Self {
709 Self::store_internal()
710 }
711
712 pub(crate) fn delete_rollback_row_required() -> Self {
714 Self::store_internal()
715 }
716
717 pub(crate) fn recovery_effect_verification_failed() -> Self {
719 Self::store_corruption()
720 }
721
722 #[cold]
724 #[inline(never)]
725 pub(crate) fn index_internal() -> Self {
726 Self::new(ErrorClass::Internal, ErrorOrigin::Index)
727 }
728
729 pub(crate) fn structural_index_removal_entity_key_required() -> Self {
731 Self::index_internal()
732 }
733
734 pub(crate) fn structural_index_insertion_entity_key_required() -> Self {
736 Self::index_internal()
737 }
738
739 pub(crate) fn index_commit_op_old_entity_key_required() -> Self {
741 Self::index_internal()
742 }
743
744 pub(crate) fn index_commit_op_new_entity_key_required() -> Self {
746 Self::index_internal()
747 }
748
749 #[cfg(test)]
751 pub(crate) fn query_internal() -> Self {
752 Self::new(ErrorClass::Internal, ErrorOrigin::Query)
753 }
754
755 #[cold]
757 #[inline(never)]
758 pub(crate) fn query_unsupported() -> Self {
759 Self::new(ErrorClass::Unsupported, ErrorOrigin::Query)
760 }
761
762 #[cold]
765 #[inline(never)]
766 pub(crate) fn query_stale_accepted_schema_revision(
767 _expected_revision: u64,
768 _current_revision: Option<u64>,
769 ) -> Self {
770 Self {
771 class: ErrorClass::Conflict,
772 origin: ErrorOrigin::Query,
773 detail: Some(ErrorDetail::Query(QueryErrorDetail::StaleSchemaRevision)),
774 }
775 }
776
777 #[cold]
779 #[inline(never)]
780 #[cfg(feature = "sql")]
781 pub(crate) fn query_schema_ddl_admission(error: SchemaDdlAdmissionError) -> Self {
782 Self {
783 class: ErrorClass::Unsupported,
784 origin: ErrorOrigin::Query,
785 detail: Some(ErrorDetail::Query(QueryErrorDetail::SchemaDdlAdmission {
786 error,
787 })),
788 }
789 }
790
791 #[cold]
793 #[inline(never)]
794 pub(crate) fn query_numeric_overflow() -> Self {
795 Self {
796 class: ErrorClass::Unsupported,
797 origin: ErrorOrigin::Query,
798 detail: Some(ErrorDetail::Query(QueryErrorDetail::NumericOverflow)),
799 }
800 }
801
802 #[cold]
805 #[inline(never)]
806 pub(crate) fn query_numeric_not_representable() -> Self {
807 Self {
808 class: ErrorClass::Unsupported,
809 origin: ErrorOrigin::Query,
810 detail: Some(ErrorDetail::Query(
811 QueryErrorDetail::NumericNotRepresentable,
812 )),
813 }
814 }
815
816 #[cold]
818 #[inline(never)]
819 pub(crate) fn serialize_internal() -> Self {
820 Self::new(ErrorClass::Internal, ErrorOrigin::Serialize)
821 }
822
823 pub(crate) fn persisted_row_encode_failed(_detail: impl Sized) -> Self {
825 Self::persisted_row_encode_internal()
826 }
827
828 pub(crate) fn persisted_row_encode_internal() -> Self {
830 Self::serialize_internal()
831 }
832
833 pub(crate) fn persisted_row_field_encode_failed(field_name: &str, _detail: impl Sized) -> Self {
835 Self::persisted_row_field_encode_internal(field_name)
836 }
837
838 pub(crate) fn persisted_row_field_encode_internal(_field_name: &str) -> Self {
840 Self::persisted_row_encode_internal()
841 }
842
843 pub(crate) fn bytes_field_value_encode_failed(_detail: impl Sized) -> Self {
845 Self::serialize_internal()
846 }
847
848 #[cold]
850 #[inline(never)]
851 pub(crate) fn store_corruption() -> Self {
852 Self::new(ErrorClass::Corruption, ErrorOrigin::Store)
853 }
854
855 pub(crate) fn commit_corruption() -> Self {
857 Self::store_corruption()
858 }
859
860 pub(crate) fn commit_component_corruption() -> Self {
862 Self::commit_corruption()
863 }
864
865 pub(crate) fn commit_id_generation_failed() -> Self {
867 Self::store_internal()
868 }
869
870 pub(crate) fn commit_marker_payload_exceeds_u32_length_limit() -> Self {
872 Self::store_unsupported()
873 }
874
875 pub(crate) fn commit_component_length_invalid() -> Self {
877 Self::commit_corruption()
878 }
879
880 pub(crate) fn commit_marker_exceeds_max_size() -> Self {
882 Self::commit_corruption()
883 }
884
885 pub(crate) fn commit_control_slot_exceeds_max_size() -> Self {
887 Self::store_unsupported()
888 }
889
890 pub(crate) fn commit_control_slot_marker_bytes_exceed_u32_length_limit() -> Self {
892 Self::store_unsupported()
893 }
894
895 pub(crate) fn startup_index_rebuild_invalid_data_key() -> Self {
897 Self::store_corruption()
898 }
899
900 #[cold]
902 #[inline(never)]
903 pub(crate) fn index_corruption() -> Self {
904 Self::new(ErrorClass::Corruption, ErrorOrigin::Index)
905 }
906
907 pub(crate) fn index_unique_validation_corruption() -> Self {
909 Self::index_plan_index_corruption()
910 }
911
912 pub(crate) fn structural_index_entry_corruption() -> Self {
914 Self::index_plan_index_corruption()
915 }
916
917 pub(crate) fn index_unique_validation_entity_key_required() -> Self {
919 Self::index_invariant()
920 }
921
922 pub(crate) fn index_unique_validation_row_deserialize_failed() -> Self {
924 Self::index_plan_serialize_corruption()
925 }
926
927 pub(crate) fn index_unique_validation_primary_key_decode_failed() -> Self {
929 Self::index_plan_serialize_corruption()
930 }
931
932 pub(crate) fn index_unique_validation_key_rebuild_failed() -> Self {
934 Self::index_plan_serialize_corruption()
935 }
936
937 pub(crate) fn index_unique_validation_row_required() -> Self {
939 Self::index_plan_store_corruption()
940 }
941
942 pub(crate) fn index_only_predicate_component_required() -> Self {
944 Self::index_invariant()
945 }
946
947 pub(crate) fn index_scan_continuation_anchor_within_envelope_required() -> Self {
949 Self::index_invariant()
950 }
951
952 pub(crate) fn index_scan_continuation_advancement_required() -> Self {
954 Self::index_invariant()
955 }
956
957 pub(crate) fn index_scan_key_corrupted_during(
959 _context: &'static str,
960 _err: impl Sized,
961 ) -> Self {
962 Self::index_corruption()
963 }
964
965 pub(crate) fn index_projection_component_required(
967 _index_name: &str,
968 _component_index: usize,
969 ) -> Self {
970 Self::index_invariant()
971 }
972
973 pub(crate) fn index_entry_decode_failed() -> Self {
975 Self::index_corruption()
976 }
977
978 pub(crate) fn serialize_corruption() -> Self {
980 Self::new(ErrorClass::Corruption, ErrorOrigin::Serialize)
981 }
982
983 pub(crate) fn persisted_row_decode_failed(_detail: impl Sized) -> Self {
985 Self::persisted_row_decode_corruption()
986 }
987
988 pub(crate) fn persisted_row_decode_corruption() -> Self {
990 Self::serialize_corruption()
991 }
992
993 pub(crate) fn persisted_row_layout_outside_accepted_window() -> Self {
995 Self {
996 class: ErrorClass::Corruption,
997 origin: ErrorOrigin::Serialize,
998 detail: Some(ErrorDetail::Serialize(
999 SerializeErrorDetail::PersistedRowLayoutOutsideAcceptedWindow,
1000 )),
1001 }
1002 }
1003
1004 pub(crate) fn persisted_row_slot_count_mismatch() -> Self {
1006 Self {
1007 class: ErrorClass::Corruption,
1008 origin: ErrorOrigin::Serialize,
1009 detail: Some(ErrorDetail::Serialize(
1010 SerializeErrorDetail::PersistedRowSlotCountMismatch,
1011 )),
1012 }
1013 }
1014
1015 pub(crate) fn persisted_row_field_decode_failed(field_name: &str, _detail: impl Sized) -> Self {
1017 Self::persisted_row_field_decode_corruption(field_name)
1018 }
1019
1020 pub(crate) fn persisted_row_field_decode_corruption(_field_name: &str) -> Self {
1022 Self::persisted_row_decode_corruption()
1023 }
1024
1025 pub(crate) fn persisted_row_field_kind_decode_failed(
1027 field_name: &str,
1028 _field_kind: impl fmt::Debug,
1029 _detail: impl Sized,
1030 ) -> Self {
1031 Self::persisted_row_field_decode_corruption(field_name)
1032 }
1033
1034 pub(crate) fn persisted_row_field_payload_exact_len_required(field_name: &str) -> Self {
1036 Self::persisted_row_field_decode_corruption(field_name)
1037 }
1038
1039 pub(crate) fn persisted_row_field_payload_must_be_empty(field_name: &str) -> Self {
1041 Self::persisted_row_field_decode_corruption(field_name)
1042 }
1043
1044 pub(crate) fn persisted_row_field_payload_invalid_byte(field_name: &str) -> Self {
1046 Self::persisted_row_field_decode_corruption(field_name)
1047 }
1048
1049 pub(crate) fn persisted_row_field_payload_non_finite(field_name: &str) -> Self {
1051 Self::persisted_row_field_decode_corruption(field_name)
1052 }
1053
1054 pub(crate) fn persisted_row_field_payload_out_of_range(field_name: &str) -> Self {
1056 Self::persisted_row_field_decode_corruption(field_name)
1057 }
1058
1059 pub(crate) fn persisted_row_field_text_payload_invalid_utf8(field_name: &str) -> Self {
1061 Self::persisted_row_field_decode_corruption(field_name)
1062 }
1063
1064 pub(crate) fn persisted_row_slot_lookup_out_of_bounds(_model_path: &str, _slot: usize) -> Self {
1066 Self::index_invariant()
1067 }
1068
1069 pub(crate) fn persisted_row_slot_cache_lookup_out_of_bounds(
1071 _model_path: &str,
1072 _slot: usize,
1073 ) -> Self {
1074 Self::index_invariant()
1075 }
1076
1077 pub(crate) fn persisted_row_primary_key_not_primary_key_encodable(
1079 _data_key: impl fmt::Debug,
1080 _detail: impl Sized,
1081 ) -> Self {
1082 Self::persisted_row_decode_corruption()
1083 }
1084
1085 pub(crate) fn persisted_row_primary_key_slot_missing(_data_key: impl fmt::Debug) -> Self {
1087 Self::persisted_row_decode_corruption()
1088 }
1089
1090 pub(crate) fn persisted_row_key_mismatch() -> Self {
1092 Self::store_corruption()
1093 }
1094
1095 pub(crate) fn persisted_row_declared_field_missing(field_name: &str) -> Self {
1097 Self::persisted_row_field_decode_corruption(field_name)
1098 }
1099
1100 pub(crate) fn data_key_entity_mismatch() -> Self {
1102 Self::store_corruption()
1103 }
1104
1105 pub(crate) fn reverse_index_ordinal_overflow(
1107 _source_path: &str,
1108 _field_name: &str,
1109 _target_path: &str,
1110 _detail: impl Sized,
1111 ) -> Self {
1112 Self::index_internal()
1113 }
1114
1115 pub(crate) fn reverse_index_entry_corrupted(
1117 _source_path: &str,
1118 _field_name: &str,
1119 _target_path: &str,
1120 _index_key: impl fmt::Debug,
1121 _detail: impl Sized,
1122 ) -> Self {
1123 Self::index_corruption()
1124 }
1125
1126 pub(crate) fn relation_target_store_missing(
1128 _source_path: &str,
1129 _field_name: &str,
1130 _target_path: &str,
1131 _store_path: &str,
1132 _detail: impl Sized,
1133 ) -> Self {
1134 Self::executor_internal()
1135 }
1136
1137 pub(crate) fn relation_target_key_decode_failed(
1139 _context_label: &str,
1140 _source_path: &str,
1141 _field_name: &str,
1142 _target_path: &str,
1143 _detail: impl Sized,
1144 ) -> Self {
1145 Self::identity_corruption()
1146 }
1147
1148 pub(crate) fn relation_target_entity_mismatch(
1150 _context_label: &str,
1151 _source_path: &str,
1152 _field_name: &str,
1153 _target_path: &str,
1154 _target_entity_name: &str,
1155 _expected_tag: impl Sized,
1156 _actual_tag: impl Sized,
1157 ) -> Self {
1158 Self::store_corruption()
1159 }
1160
1161 pub(crate) fn relation_source_row_decode_failed(
1163 _source_path: &str,
1164 _field_name: &str,
1165 _target_path: &str,
1166 _detail: impl Sized,
1167 ) -> Self {
1168 Self::persisted_row_decode_corruption()
1169 }
1170
1171 pub(crate) fn relation_source_row_unsupported_scalar_relation_key(
1173 _source_path: &str,
1174 _field_name: &str,
1175 _target_path: &str,
1176 ) -> Self {
1177 Self::persisted_row_decode_corruption()
1178 }
1179
1180 pub(crate) fn relation_source_row_unsupported_key_kind(_field_kind: impl fmt::Debug) -> Self {
1182 Self::persisted_row_decode_corruption()
1183 }
1184
1185 pub(crate) fn reverse_index_relation_target_decode_invariant_violated(
1187 _source_path: &str,
1188 _field_name: &str,
1189 _target_path: &str,
1190 ) -> Self {
1191 Self::executor_internal()
1192 }
1193
1194 pub(crate) fn bytes_covering_component_payload_empty() -> Self {
1196 Self::index_corruption()
1197 }
1198
1199 pub(crate) fn bytes_covering_bool_payload_truncated() -> Self {
1201 Self::index_corruption()
1202 }
1203
1204 pub(crate) fn bytes_covering_component_payload_invalid_length() -> Self {
1206 Self::index_corruption()
1207 }
1208
1209 pub(crate) fn bytes_covering_bool_payload_invalid_value() -> Self {
1211 Self::index_corruption()
1212 }
1213
1214 pub(crate) fn bytes_covering_text_payload_invalid_terminator() -> Self {
1216 Self::index_corruption()
1217 }
1218
1219 pub(crate) fn bytes_covering_text_payload_trailing_bytes() -> Self {
1221 Self::index_corruption()
1222 }
1223
1224 pub(crate) fn bytes_covering_text_payload_invalid_utf8() -> Self {
1226 Self::index_corruption()
1227 }
1228
1229 pub(crate) fn bytes_covering_text_payload_invalid_escape_byte() -> Self {
1231 Self::index_corruption()
1232 }
1233
1234 pub(crate) fn bytes_covering_text_payload_missing_terminator() -> Self {
1236 Self::index_corruption()
1237 }
1238
1239 #[must_use]
1241 pub fn missing_persisted_slot(field_name: &'static str) -> Self {
1242 Self::persisted_row_field_decode_corruption(field_name)
1243 }
1244
1245 pub(crate) fn identity_corruption() -> Self {
1247 Self::new(ErrorClass::Corruption, ErrorOrigin::Identity)
1248 }
1249
1250 #[cold]
1252 #[inline(never)]
1253 pub(crate) fn store_unsupported() -> Self {
1254 Self::new(ErrorClass::Unsupported, ErrorOrigin::Store)
1255 }
1256
1257 #[cfg(any(test, feature = "sql"))]
1259 pub(crate) fn schema_ddl_publication_race_lost(_entity_path: &'static str) -> Self {
1260 Self {
1261 class: ErrorClass::Unsupported,
1262 origin: ErrorOrigin::Store,
1263 detail: Some(ErrorDetail::Store(StoreError::SchemaDdlPublicationRaceLost)),
1264 }
1265 }
1266
1267 #[cfg(feature = "sql")]
1269 pub(crate) fn schema_ddl_rewrite_requires_migration(_entity_path: &'static str) -> Self {
1270 Self {
1271 class: ErrorClass::Unsupported,
1272 origin: ErrorOrigin::Store,
1273 detail: Some(ErrorDetail::Store(
1274 StoreError::SchemaDdlRewriteRequiresMigration,
1275 )),
1276 }
1277 }
1278
1279 pub(crate) fn schema_row_layout_version_exhausted() -> Self {
1281 Self {
1282 class: ErrorClass::Unsupported,
1283 origin: ErrorOrigin::Store,
1284 detail: Some(ErrorDetail::Store(
1285 StoreError::SchemaRowLayoutVersionExhausted,
1286 )),
1287 }
1288 }
1289
1290 pub(crate) fn journal_mutation_revision_exhausted() -> Self {
1292 Self {
1293 class: ErrorClass::Unsupported,
1294 origin: ErrorOrigin::Store,
1295 detail: Some(ErrorDetail::Store(
1296 StoreError::JournalMutationRevisionExhausted,
1297 )),
1298 }
1299 }
1300
1301 pub(crate) fn schema_generated_field_after_ddl_field() -> Self {
1304 Self {
1305 class: ErrorClass::Unsupported,
1306 origin: ErrorOrigin::Store,
1307 detail: Some(ErrorDetail::Store(
1308 StoreError::SchemaGeneratedFieldAfterDdlField,
1309 )),
1310 }
1311 }
1312
1313 pub(crate) fn schema_generated_constraint_activation_stale() -> Self {
1316 Self {
1317 class: ErrorClass::Conflict,
1318 origin: ErrorOrigin::Store,
1319 detail: Some(ErrorDetail::Store(
1320 StoreError::SchemaGeneratedConstraintActivationStale,
1321 )),
1322 }
1323 }
1324
1325 pub(crate) fn schema_transition_budget_exceeded(
1327 resource: SchemaTransitionBudgetResource,
1328 ) -> Self {
1329 Self {
1330 class: ErrorClass::Unsupported,
1331 origin: ErrorOrigin::Store,
1332 detail: Some(ErrorDetail::Store(
1333 StoreError::SchemaTransitionBudgetExceeded { resource },
1334 )),
1335 }
1336 }
1337
1338 pub(crate) fn unsupported_entity_tag_in_data_store(
1340 _entity_tag: crate::types::EntityTag,
1341 ) -> Self {
1342 Self::store_unsupported()
1343 }
1344
1345 #[cfg(not(test))]
1347 pub(crate) fn commit_memory_id_registration_failed(_err: impl Sized) -> Self {
1348 Self::store_internal()
1349 }
1350
1351 pub(crate) fn index_unsupported() -> Self {
1353 Self::new(ErrorClass::Unsupported, ErrorOrigin::Index)
1354 }
1355
1356 pub(crate) fn index_component_exceeds_max_size() -> Self {
1358 Self::index_unsupported()
1359 }
1360
1361 pub(crate) fn serialize_unsupported() -> Self {
1363 Self::new(ErrorClass::Unsupported, ErrorOrigin::Serialize)
1364 }
1365
1366 pub(crate) fn cursor_invalid_continuation() -> Self {
1368 Self::new(ErrorClass::Unsupported, ErrorOrigin::Cursor)
1369 }
1370
1371 pub(crate) fn serialize_incompatible_persisted_format() -> Self {
1373 Self::new(
1374 ErrorClass::IncompatiblePersistedFormat,
1375 ErrorOrigin::Serialize,
1376 )
1377 }
1378
1379 #[cfg(feature = "sql")]
1382 pub(crate) fn query_unsupported_sql_feature(feature: diagnostic_code::SqlFeatureCode) -> Self {
1383 Self {
1384 class: ErrorClass::Unsupported,
1385 origin: ErrorOrigin::Query,
1386 detail: Some(ErrorDetail::Query(
1387 QueryErrorDetail::UnsupportedSqlFeature { feature },
1388 )),
1389 }
1390 }
1391
1392 #[cfg(feature = "sql")]
1395 pub(crate) fn query_sql_lowering(reason: diagnostic_code::SqlLoweringCode) -> Self {
1396 Self {
1397 class: ErrorClass::Unsupported,
1398 origin: ErrorOrigin::Query,
1399 detail: Some(ErrorDetail::Query(QueryErrorDetail::SqlLowering { reason })),
1400 }
1401 }
1402
1403 pub(crate) fn query_unsupported_projection(
1406 reason: diagnostic_code::QueryProjectionCode,
1407 ) -> Self {
1408 Self {
1409 class: ErrorClass::Unsupported,
1410 origin: ErrorOrigin::Query,
1411 detail: Some(ErrorDetail::Query(
1412 QueryErrorDetail::UnsupportedProjection { reason },
1413 )),
1414 }
1415 }
1416
1417 pub(crate) fn query_unknown_aggregate_target_field() -> Self {
1419 Self {
1420 class: ErrorClass::Unsupported,
1421 origin: ErrorOrigin::Query,
1422 detail: Some(ErrorDetail::Query(
1423 QueryErrorDetail::UnknownAggregateTargetField,
1424 )),
1425 }
1426 }
1427
1428 pub(crate) fn query_result_shape_mismatch(
1431 reason: diagnostic_code::QueryResultShapeCode,
1432 ) -> Self {
1433 Self {
1434 class: ErrorClass::Unsupported,
1435 origin: ErrorOrigin::Query,
1436 detail: Some(ErrorDetail::Query(QueryErrorDetail::ResultShapeMismatch {
1437 reason,
1438 })),
1439 }
1440 }
1441
1442 #[cfg(feature = "sql")]
1445 pub(crate) fn query_sql_surface_mismatch(
1446 mismatch: diagnostic_code::SqlSurfaceMismatchCode,
1447 ) -> Self {
1448 Self {
1449 class: ErrorClass::Unsupported,
1450 origin: ErrorOrigin::Query,
1451 detail: Some(ErrorDetail::Query(QueryErrorDetail::SqlSurfaceMismatch {
1452 mismatch,
1453 })),
1454 }
1455 }
1456
1457 pub(crate) fn query_sql_write_boundary(
1459 boundary: diagnostic_code::SqlWriteBoundaryCode,
1460 ) -> Self {
1461 Self {
1462 class: ErrorClass::Unsupported,
1463 origin: ErrorOrigin::Query,
1464 detail: Some(ErrorDetail::Query(QueryErrorDetail::SqlWriteBoundary {
1465 boundary,
1466 })),
1467 }
1468 }
1469
1470 pub fn store_not_found(_key: impl Sized) -> Self {
1471 Self {
1472 class: ErrorClass::NotFound,
1473 origin: ErrorOrigin::Store,
1474 detail: Some(ErrorDetail::Store(StoreError::NotFound)),
1475 }
1476 }
1477
1478 pub fn unsupported_entity_path(_path: impl Sized) -> Self {
1480 Self::store_unsupported()
1481 }
1482
1483 #[must_use]
1484 pub const fn is_not_found(&self) -> bool {
1485 matches!(self.detail, Some(ErrorDetail::Store(StoreError::NotFound)))
1486 }
1487
1488 #[cold]
1490 #[inline(never)]
1491 pub(crate) fn index_plan_corruption(origin: ErrorOrigin) -> Self {
1492 Self::new(ErrorClass::Corruption, origin)
1493 }
1494
1495 #[cold]
1497 #[inline(never)]
1498 pub(crate) fn index_plan_index_corruption() -> Self {
1499 Self::index_plan_corruption(ErrorOrigin::Index)
1500 }
1501
1502 #[cold]
1504 #[inline(never)]
1505 pub(crate) fn index_plan_store_corruption() -> Self {
1506 Self::index_plan_corruption(ErrorOrigin::Store)
1507 }
1508
1509 #[cold]
1511 #[inline(never)]
1512 pub(crate) fn index_plan_serialize_corruption() -> Self {
1513 Self::index_plan_corruption(ErrorOrigin::Serialize)
1514 }
1515
1516 #[cfg(test)]
1518 pub(crate) fn index_plan_invariant(origin: ErrorOrigin) -> Self {
1519 Self::new(ErrorClass::InvariantViolation, origin)
1520 }
1521
1522 #[cfg(test)]
1524 pub(crate) fn index_plan_store_invariant() -> Self {
1525 Self::index_plan_invariant(ErrorOrigin::Store)
1526 }
1527
1528 pub(crate) fn index_violation(_path: &str, _index_fields: &[&str]) -> Self {
1530 Self::new(ErrorClass::Conflict, ErrorOrigin::Index)
1531 }
1532}
1533
1534impl From<diagnostic_code::QueryReadAdmissionCode> for InternalError {
1535 fn from(reason: diagnostic_code::QueryReadAdmissionCode) -> Self {
1536 Self {
1537 class: ErrorClass::Unsupported,
1538 origin: ErrorOrigin::Query,
1539 detail: Some(ErrorDetail::Query(QueryErrorDetail::QueryReadAdmission {
1540 reason,
1541 })),
1542 }
1543 }
1544}
1545
1546impl fmt::Debug for InternalError {
1547 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1548 fmt_compact_diagnostic(
1549 f,
1550 self.diagnostic_code(),
1551 self.detail
1552 .as_ref()
1553 .and_then(ErrorDetail::diagnostic_detail),
1554 )
1555 }
1556}
1557
1558impl fmt::Display for InternalError {
1559 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1560 f.write_str(self.message())
1561 }
1562}
1563
1564impl std::error::Error for InternalError {}
1565
1566#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
1574pub enum ConstraintDiagnosticKind {
1575 Check,
1577
1578 NotNull,
1580
1581 Relation,
1583
1584 Unique,
1586}
1587
1588impl ConstraintDiagnosticKind {
1589 #[must_use]
1591 pub const fn as_str(self) -> &'static str {
1592 match self {
1593 Self::Check => "check",
1594 Self::NotNull => "not_null",
1595 Self::Relation => "relation",
1596 Self::Unique => "unique",
1597 }
1598 }
1599}
1600
1601#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
1609pub enum ConstraintDiagnosticContext {
1610 Integrity,
1612
1613 MigrationValidation,
1615
1616 WriteAdmission,
1618}
1619
1620impl ConstraintDiagnosticContext {
1621 #[must_use]
1623 pub const fn as_str(self) -> &'static str {
1624 match self {
1625 Self::Integrity => "integrity",
1626 Self::MigrationValidation => "migration_validation",
1627 Self::WriteAdmission => "write_admission",
1628 }
1629 }
1630}
1631
1632#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
1641pub struct ConstraintDiagnostic {
1642 constraint_id: u32,
1643 constraint_name: String,
1644 constraint_kind: ConstraintDiagnosticKind,
1645 entity: String,
1646 primary_key: Option<Vec<u8>>,
1647 field_paths: Vec<String>,
1648 context: ConstraintDiagnosticContext,
1649 error_code: u16,
1650}
1651
1652impl ConstraintDiagnostic {
1653 #[must_use]
1655 pub(crate) const fn write_violation(
1656 constraint_id: u32,
1657 constraint_name: String,
1658 constraint_kind: ConstraintDiagnosticKind,
1659 entity: String,
1660 primary_key: Option<Vec<u8>>,
1661 field_paths: Vec<String>,
1662 ) -> Self {
1663 Self {
1664 constraint_id,
1665 constraint_name,
1666 constraint_kind,
1667 entity,
1668 primary_key,
1669 field_paths,
1670 context: ConstraintDiagnosticContext::WriteAdmission,
1671 error_code: diagnostic_code::ErrorCode::RUNTIME_BOUNDARY_CONSTRAINT_VIOLATION.raw(),
1672 }
1673 }
1674
1675 #[must_use]
1677 pub(crate) const fn write_activation_blocked(
1678 constraint_id: u32,
1679 constraint_name: String,
1680 constraint_kind: ConstraintDiagnosticKind,
1681 entity: String,
1682 primary_key: Option<Vec<u8>>,
1683 field_paths: Vec<String>,
1684 ) -> Self {
1685 Self {
1686 constraint_id,
1687 constraint_name,
1688 constraint_kind,
1689 entity,
1690 primary_key,
1691 field_paths,
1692 context: ConstraintDiagnosticContext::WriteAdmission,
1693 error_code:
1694 diagnostic_code::ErrorCode::RUNTIME_BOUNDARY_CONSTRAINT_ACTIVATION_WRITE_BLOCKED
1695 .raw(),
1696 }
1697 }
1698
1699 #[cfg(feature = "sql")]
1701 #[must_use]
1702 pub(crate) const fn migration_validation(
1703 constraint_id: u32,
1704 constraint_name: String,
1705 constraint_kind: ConstraintDiagnosticKind,
1706 entity: String,
1707 primary_key: Vec<u8>,
1708 field_paths: Vec<String>,
1709 error_code: u16,
1710 ) -> Self {
1711 Self {
1712 constraint_id,
1713 constraint_name,
1714 constraint_kind,
1715 entity,
1716 primary_key: Some(primary_key),
1717 field_paths,
1718 context: ConstraintDiagnosticContext::MigrationValidation,
1719 error_code,
1720 }
1721 }
1722
1723 #[must_use]
1725 pub const fn constraint_id(&self) -> u32 {
1726 self.constraint_id
1727 }
1728
1729 #[must_use]
1731 pub const fn constraint_name(&self) -> &str {
1732 self.constraint_name.as_str()
1733 }
1734
1735 #[must_use]
1737 pub const fn constraint_kind(&self) -> ConstraintDiagnosticKind {
1738 self.constraint_kind
1739 }
1740
1741 #[must_use]
1743 pub const fn entity(&self) -> &str {
1744 self.entity.as_str()
1745 }
1746
1747 #[must_use]
1749 pub fn primary_key(&self) -> Option<&[u8]> {
1750 self.primary_key.as_deref()
1751 }
1752
1753 #[must_use]
1755 pub const fn field_paths(&self) -> &[String] {
1756 self.field_paths.as_slice()
1757 }
1758
1759 #[must_use]
1761 pub const fn context(&self) -> ConstraintDiagnosticContext {
1762 self.context
1763 }
1764
1765 #[must_use]
1767 pub const fn error_code(&self) -> diagnostic_code::ErrorCode {
1768 diagnostic_code::ErrorCode::from_raw(self.error_code)
1769 }
1770
1771 #[must_use]
1773 pub const fn error_class(&self) -> diagnostic_code::ErrorClass {
1774 self.error_code().class()
1775 }
1776}
1777
1778pub enum ErrorDetail {
1786 Executor(ExecutorErrorDetail),
1788 Store(StoreError),
1789 Query(QueryErrorDetail),
1790 Recovery(RecoveryErrorDetail),
1791 Serialize(SerializeErrorDetail),
1793 }
1796
1797pub enum ExecutorErrorDetail {
1799 MutationRequiredFieldMissing,
1801 ConstraintViolation {
1803 diagnostic: Box<ConstraintDiagnostic>,
1804 },
1805 AcceptedRowConstraintProgramCorrupt,
1807 ConstraintActivationWriteBlocked {
1809 diagnostic: Box<ConstraintDiagnostic>,
1810 },
1811}
1812
1813impl ExecutorErrorDetail {
1814 #[must_use]
1816 pub fn constraint_diagnostic(&self) -> Option<&ConstraintDiagnostic> {
1817 match self {
1818 Self::ConstraintActivationWriteBlocked { diagnostic }
1819 | Self::ConstraintViolation { diagnostic } => Some(diagnostic.as_ref()),
1820 Self::MutationRequiredFieldMissing | Self::AcceptedRowConstraintProgramCorrupt => None,
1821 }
1822 }
1823}
1824
1825pub enum SerializeErrorDetail {
1827 PersistedRowLayoutOutsideAcceptedWindow,
1829
1830 PersistedRowSlotCountMismatch,
1832}
1833
1834pub enum RecoveryErrorDetail {
1841 UnsupportedFormatVersion { found: Option<u16>, required: u16 },
1842
1843 MalformedFormatMarker { reason: RecoveryFormatMarkerError },
1844}
1845
1846#[derive(Clone, Copy, Eq, PartialEq)]
1848pub enum RecoveryFormatMarkerError {
1849 Magic,
1850 Checksum,
1851 State,
1852}
1853
1854pub enum StoreError {
1862 NotFound,
1863
1864 Corrupt,
1865
1866 InvariantViolation,
1867
1868 SchemaDdlPublicationRaceLost,
1869
1870 SchemaDdlRewriteRequiresMigration,
1871
1872 SchemaRowLayoutVersionExhausted,
1873
1874 JournalMutationRevisionExhausted,
1875
1876 SchemaTransitionBudgetExceeded {
1877 resource: SchemaTransitionBudgetResource,
1878 },
1879
1880 SchemaGeneratedFieldAfterDdlField,
1882
1883 SchemaGeneratedConstraintActivationStale,
1885}
1886
1887pub enum QueryErrorDetail {
1894 NumericOverflow,
1895
1896 NumericNotRepresentable,
1897
1898 UnsupportedSqlFeature {
1899 feature: diagnostic_code::SqlFeatureCode,
1900 },
1901
1902 SqlLowering {
1903 reason: diagnostic_code::SqlLoweringCode,
1904 },
1905
1906 UnsupportedProjection {
1907 reason: diagnostic_code::QueryProjectionCode,
1908 },
1909
1910 UnknownAggregateTargetField,
1911
1912 ResultShapeMismatch {
1913 reason: diagnostic_code::QueryResultShapeCode,
1914 },
1915
1916 QueryReadAdmission {
1917 reason: diagnostic_code::QueryReadAdmissionCode,
1918 },
1919
1920 SqlSurfaceMismatch {
1921 mismatch: diagnostic_code::SqlSurfaceMismatchCode,
1922 },
1923
1924 SqlWriteBoundary {
1925 boundary: diagnostic_code::SqlWriteBoundaryCode,
1926 },
1927
1928 SchemaDdlAdmission {
1929 error: SchemaDdlAdmissionError,
1930 },
1931
1932 StaleSchemaRevision,
1933}
1934
1935impl fmt::Display for QueryErrorDetail {
1936 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1937 f.write_str(COMPACT_QUERY_DIAGNOSTIC_MESSAGE)
1938 }
1939}
1940
1941impl std::error::Error for QueryErrorDetail {}
1942
1943#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1951pub enum SchemaTransitionBudgetResource {
1952 DeletionKeys,
1954 ProjectionEntries,
1956 ProjectionWorkUnits,
1958 SourceRows,
1960 SourceRowBytes,
1962 StagedRawBytes,
1964}
1965
1966#[derive(Clone, Copy, Eq, PartialEq)]
1975pub enum SchemaDdlAdmissionError {
1976 MissingExpectedSchemaVersion,
1977
1978 MissingNextSchemaVersion,
1979
1980 StaleExpectedSchemaVersion,
1981
1982 InvalidExpectedSchemaVersion,
1983
1984 InvalidNextSchemaVersion,
1985
1986 AcceptedSchemaChangeWithoutVersionBump,
1987
1988 EmptyVersionBump,
1989
1990 VersionGap,
1991
1992 VersionRollback,
1993
1994 FingerprintMethodMismatch,
1995
1996 UnsupportedTransitionClass,
1997
1998 PhysicalRunnerMissing,
1999
2000 ValidationFailed,
2001
2002 PublicationRaceLost,
2003
2004 InvalidAddColumnDefault,
2005
2006 InvalidAlterColumnDefault,
2007
2008 RowLayoutVersionExhausted,
2009
2010 GeneratedIndexDropRejected,
2011
2012 SchemaRewriteRequiresMigration,
2013
2014 SchemaTransitionBudgetExceeded {
2015 resource: SchemaTransitionBudgetResource,
2016 },
2017
2018 GeneratedFieldDefaultChangeRejected,
2019
2020 GeneratedFieldNullabilityChangeRejected,
2021}
2022
2023impl fmt::Display for SchemaDdlAdmissionError {
2024 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2025 f.write_str(COMPACT_QUERY_DIAGNOSTIC_MESSAGE)
2026 }
2027}
2028
2029impl std::error::Error for SchemaDdlAdmissionError {}
2030
2031impl fmt::Debug for ErrorDetail {
2032 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2033 fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
2034 }
2035}
2036
2037impl fmt::Debug for ExecutorErrorDetail {
2038 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2039 fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
2040 }
2041}
2042
2043impl fmt::Debug for StoreError {
2044 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2045 fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
2046 }
2047}
2048
2049impl fmt::Debug for QueryErrorDetail {
2050 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2051 fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
2052 }
2053}
2054
2055impl fmt::Debug for RecoveryErrorDetail {
2056 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2057 fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
2058 }
2059}
2060
2061impl fmt::Debug for SerializeErrorDetail {
2062 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2063 fmt_compact_diagnostic(f, self.diagnostic_code(), self.diagnostic_detail())
2064 }
2065}
2066
2067impl fmt::Debug for RecoveryFormatMarkerError {
2068 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2069 fmt_compact_diagnostic(
2070 f,
2071 diagnostic_code::DiagnosticCode::RuntimeCorruption,
2072 Some(diagnostic_code::DiagnosticDetail::RuntimeKind {
2073 kind: diagnostic_code::RuntimeErrorKind::Corruption,
2074 }),
2075 )
2076 }
2077}
2078
2079impl fmt::Debug for SchemaDdlAdmissionError {
2080 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2081 fmt_compact_diagnostic(
2082 f,
2083 diagnostic_code::DiagnosticCode::SchemaDdlAdmission,
2084 Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
2085 reason: self.diagnostic_code(),
2086 }),
2087 )
2088 }
2089}
2090
2091fn fmt_compact_diagnostic(
2092 f: &mut fmt::Formatter<'_>,
2093 code: diagnostic_code::DiagnosticCode,
2094 detail: Option<diagnostic_code::DiagnosticDetail>,
2095) -> fmt::Result {
2096 write!(
2097 f,
2098 "{}",
2099 diagnostic_code::ErrorCode::from_parts(code, detail).raw()
2100 )
2101}
2102
2103impl ErrorDetail {
2104 #[must_use]
2106 pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
2107 match self {
2108 Self::Executor(error) => error.diagnostic_code(),
2109 Self::Store(error) => error.diagnostic_code(),
2110 Self::Query(error) => error.diagnostic_code(),
2111 Self::Recovery(error) => error.diagnostic_code(),
2112 Self::Serialize(error) => error.diagnostic_code(),
2113 }
2114 }
2115
2116 #[must_use]
2118 pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
2119 match self {
2120 Self::Executor(error) => error.diagnostic_detail(),
2121 Self::Store(error) => error.diagnostic_detail(),
2122 Self::Query(error) => error.diagnostic_detail(),
2123 Self::Recovery(error) => error.diagnostic_detail(),
2124 Self::Serialize(error) => error.diagnostic_detail(),
2125 }
2126 }
2127}
2128
2129impl ExecutorErrorDetail {
2130 #[must_use]
2132 pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
2133 match self {
2134 Self::MutationRequiredFieldMissing => {
2135 diagnostic_code::DiagnosticCode::RuntimeUnsupported
2136 }
2137 Self::ConstraintViolation { diagnostic }
2138 | Self::ConstraintActivationWriteBlocked { diagnostic } => {
2139 diagnostic.error_code().diagnostic_code()
2140 }
2141 Self::AcceptedRowConstraintProgramCorrupt => {
2142 diagnostic_code::DiagnosticCode::RuntimeCorruption
2143 }
2144 }
2145 }
2146
2147 #[must_use]
2149 pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
2150 match self {
2151 Self::MutationRequiredFieldMissing => {
2152 Some(diagnostic_code::DiagnosticDetail::RuntimeBoundary {
2153 boundary: diagnostic_code::RuntimeBoundaryCode::MutationRequiredFieldMissing,
2154 })
2155 }
2156 Self::ConstraintViolation { diagnostic }
2157 | Self::ConstraintActivationWriteBlocked { diagnostic } => {
2158 diagnostic.error_code().diagnostic_detail()
2159 }
2160 Self::AcceptedRowConstraintProgramCorrupt => {
2161 Some(diagnostic_code::DiagnosticDetail::RuntimeBoundary {
2162 boundary:
2163 diagnostic_code::RuntimeBoundaryCode::AcceptedRowConstraintProgramCorrupt,
2164 })
2165 }
2166 }
2167 }
2168}
2169
2170impl RecoveryErrorDetail {
2171 #[must_use]
2173 pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
2174 match self {
2175 Self::UnsupportedFormatVersion { .. } => {
2176 diagnostic_code::DiagnosticCode::RuntimeIncompatiblePersistedFormat
2177 }
2178 Self::MalformedFormatMarker { .. } => {
2179 diagnostic_code::DiagnosticCode::RuntimeCorruption
2180 }
2181 }
2182 }
2183
2184 #[must_use]
2186 pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
2187 let kind = match self {
2188 Self::UnsupportedFormatVersion { .. } => {
2189 diagnostic_code::RuntimeErrorKind::IncompatiblePersistedFormat
2190 }
2191 Self::MalformedFormatMarker { .. } => diagnostic_code::RuntimeErrorKind::Corruption,
2192 };
2193
2194 Some(diagnostic_code::DiagnosticDetail::RuntimeKind { kind })
2195 }
2196}
2197
2198impl SerializeErrorDetail {
2199 #[must_use]
2201 pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
2202 match self {
2203 Self::PersistedRowLayoutOutsideAcceptedWindow | Self::PersistedRowSlotCountMismatch => {
2204 diagnostic_code::DiagnosticCode::RuntimeCorruption
2205 }
2206 }
2207 }
2208
2209 #[must_use]
2211 pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
2212 let boundary = match self {
2213 Self::PersistedRowLayoutOutsideAcceptedWindow => {
2214 diagnostic_code::RuntimeBoundaryCode::PersistedRowLayoutOutsideAcceptedWindow
2215 }
2216 Self::PersistedRowSlotCountMismatch => {
2217 diagnostic_code::RuntimeBoundaryCode::PersistedRowSlotCountMismatch
2218 }
2219 };
2220
2221 Some(diagnostic_code::DiagnosticDetail::RuntimeBoundary { boundary })
2222 }
2223}
2224
2225impl StoreError {
2226 #[must_use]
2228 pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
2229 match self {
2230 Self::NotFound => diagnostic_code::DiagnosticCode::StoreNotFound,
2231 Self::Corrupt => diagnostic_code::DiagnosticCode::StoreCorruption,
2232 Self::InvariantViolation => diagnostic_code::DiagnosticCode::StoreInvariantViolation,
2233 Self::SchemaDdlPublicationRaceLost
2234 | Self::SchemaDdlRewriteRequiresMigration
2235 | Self::SchemaRowLayoutVersionExhausted
2236 | Self::SchemaTransitionBudgetExceeded { .. } => {
2237 diagnostic_code::DiagnosticCode::SchemaDdlAdmission
2238 }
2239 Self::JournalMutationRevisionExhausted | Self::SchemaGeneratedFieldAfterDdlField => {
2240 diagnostic_code::DiagnosticCode::RuntimeUnsupported
2241 }
2242 Self::SchemaGeneratedConstraintActivationStale => {
2243 diagnostic_code::DiagnosticCode::RuntimeConflict
2244 }
2245 }
2246 }
2247
2248 #[must_use]
2250 pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
2251 match self {
2252 Self::SchemaDdlPublicationRaceLost => {
2253 Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
2254 reason: diagnostic_code::SchemaDdlAdmissionCode::PublicationRaceLost,
2255 })
2256 }
2257 Self::SchemaDdlRewriteRequiresMigration => {
2258 Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
2259 reason: diagnostic_code::SchemaDdlAdmissionCode::SchemaRewriteRequiresMigration,
2260 })
2261 }
2262 Self::SchemaRowLayoutVersionExhausted => {
2263 Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
2264 reason: diagnostic_code::SchemaDdlAdmissionCode::RowLayoutVersionExhausted,
2265 })
2266 }
2267 Self::JournalMutationRevisionExhausted => {
2268 Some(diagnostic_code::DiagnosticDetail::RuntimeBoundary {
2269 boundary:
2270 diagnostic_code::RuntimeBoundaryCode::JournalMutationRevisionExhausted,
2271 })
2272 }
2273 Self::SchemaTransitionBudgetExceeded { .. } => {
2274 Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
2275 reason: diagnostic_code::SchemaDdlAdmissionCode::SchemaTransitionBudgetExceeded,
2276 })
2277 }
2278 Self::SchemaGeneratedFieldAfterDdlField => {
2279 Some(diagnostic_code::DiagnosticDetail::RuntimeBoundary {
2280 boundary: diagnostic_code::RuntimeBoundaryCode::GeneratedFieldAfterDdlField,
2281 })
2282 }
2283 Self::SchemaGeneratedConstraintActivationStale => {
2284 Some(diagnostic_code::DiagnosticDetail::RuntimeBoundary {
2285 boundary:
2286 diagnostic_code::RuntimeBoundaryCode::GeneratedConstraintActivationStale,
2287 })
2288 }
2289 Self::NotFound | Self::Corrupt | Self::InvariantViolation => None,
2290 }
2291 }
2292}
2293
2294impl QueryErrorDetail {
2295 #[must_use]
2297 pub const fn diagnostic_code(&self) -> diagnostic_code::DiagnosticCode {
2298 match self {
2299 Self::NumericOverflow => diagnostic_code::DiagnosticCode::QueryNumericOverflow,
2300 Self::NumericNotRepresentable => {
2301 diagnostic_code::DiagnosticCode::QueryNumericNotRepresentable
2302 }
2303 Self::UnsupportedSqlFeature { .. } => {
2304 diagnostic_code::DiagnosticCode::QueryUnsupportedSqlFeature
2305 }
2306 Self::SqlLowering { .. } => diagnostic_code::DiagnosticCode::QueryUnsupportedSqlFeature,
2307 Self::UnsupportedProjection { .. } => {
2308 diagnostic_code::DiagnosticCode::QueryUnsupportedProjection
2309 }
2310 Self::UnknownAggregateTargetField => {
2311 diagnostic_code::DiagnosticCode::QueryUnknownAggregateTargetField
2312 }
2313 Self::ResultShapeMismatch { .. } => {
2314 diagnostic_code::DiagnosticCode::QueryResultShapeMismatch
2315 }
2316 Self::QueryReadAdmission { .. } => diagnostic_code::DiagnosticCode::QueryReadAdmission,
2317 Self::SqlSurfaceMismatch { .. } => {
2318 diagnostic_code::DiagnosticCode::QuerySqlSurfaceMismatch
2319 }
2320 Self::SqlWriteBoundary { .. } => diagnostic_code::DiagnosticCode::QuerySqlWriteBoundary,
2321 Self::SchemaDdlAdmission { .. } => diagnostic_code::DiagnosticCode::SchemaDdlAdmission,
2322 Self::StaleSchemaRevision => diagnostic_code::DiagnosticCode::RuntimeConflict,
2323 }
2324 }
2325
2326 #[must_use]
2328 pub const fn diagnostic_detail(&self) -> Option<diagnostic_code::DiagnosticDetail> {
2329 match self {
2330 Self::UnsupportedSqlFeature { feature } => {
2331 Some(diagnostic_code::DiagnosticDetail::UnsupportedSqlFeature { feature: *feature })
2332 }
2333 Self::SqlLowering { reason } => {
2334 Some(diagnostic_code::DiagnosticDetail::SqlLowering { reason: *reason })
2335 }
2336 Self::UnsupportedProjection { reason } => {
2337 Some(diagnostic_code::DiagnosticDetail::QueryProjection { reason: *reason })
2338 }
2339 Self::ResultShapeMismatch { reason } => {
2340 Some(diagnostic_code::DiagnosticDetail::QueryResultShape { reason: *reason })
2341 }
2342 Self::QueryReadAdmission { reason } => {
2343 Some(diagnostic_code::DiagnosticDetail::QueryReadAdmission { reason: *reason })
2344 }
2345 Self::SqlSurfaceMismatch { mismatch } => {
2346 Some(diagnostic_code::DiagnosticDetail::SqlSurfaceMismatch {
2347 mismatch: *mismatch,
2348 })
2349 }
2350 Self::SqlWriteBoundary { boundary } => {
2351 Some(diagnostic_code::DiagnosticDetail::SqlWriteBoundary {
2352 boundary: *boundary,
2353 })
2354 }
2355 Self::SchemaDdlAdmission { error } => {
2356 Some(diagnostic_code::DiagnosticDetail::SchemaDdlAdmission {
2357 reason: error.diagnostic_code(),
2358 })
2359 }
2360 Self::NumericOverflow
2361 | Self::NumericNotRepresentable
2362 | Self::UnknownAggregateTargetField
2363 | Self::StaleSchemaRevision => None,
2364 }
2365 }
2366}
2367
2368impl SchemaDdlAdmissionError {
2369 #[must_use]
2371 pub const fn diagnostic_code(&self) -> diagnostic_code::SchemaDdlAdmissionCode {
2372 match self {
2373 Self::MissingExpectedSchemaVersion => {
2374 diagnostic_code::SchemaDdlAdmissionCode::MissingExpectedSchemaVersion
2375 }
2376 Self::MissingNextSchemaVersion => {
2377 diagnostic_code::SchemaDdlAdmissionCode::MissingNextSchemaVersion
2378 }
2379 Self::StaleExpectedSchemaVersion => {
2380 diagnostic_code::SchemaDdlAdmissionCode::StaleExpectedSchemaVersion
2381 }
2382 Self::InvalidExpectedSchemaVersion => {
2383 diagnostic_code::SchemaDdlAdmissionCode::InvalidExpectedSchemaVersion
2384 }
2385 Self::InvalidNextSchemaVersion => {
2386 diagnostic_code::SchemaDdlAdmissionCode::InvalidNextSchemaVersion
2387 }
2388 Self::AcceptedSchemaChangeWithoutVersionBump => {
2389 diagnostic_code::SchemaDdlAdmissionCode::AcceptedSchemaChangeWithoutVersionBump
2390 }
2391 Self::EmptyVersionBump => diagnostic_code::SchemaDdlAdmissionCode::EmptyVersionBump,
2392 Self::VersionGap => diagnostic_code::SchemaDdlAdmissionCode::VersionGap,
2393 Self::VersionRollback => diagnostic_code::SchemaDdlAdmissionCode::VersionRollback,
2394 Self::FingerprintMethodMismatch => {
2395 diagnostic_code::SchemaDdlAdmissionCode::FingerprintMethodMismatch
2396 }
2397 Self::UnsupportedTransitionClass => {
2398 diagnostic_code::SchemaDdlAdmissionCode::UnsupportedTransitionClass
2399 }
2400 Self::PhysicalRunnerMissing => {
2401 diagnostic_code::SchemaDdlAdmissionCode::PhysicalRunnerMissing
2402 }
2403 Self::ValidationFailed => diagnostic_code::SchemaDdlAdmissionCode::ValidationFailed,
2404 Self::PublicationRaceLost => {
2405 diagnostic_code::SchemaDdlAdmissionCode::PublicationRaceLost
2406 }
2407 Self::InvalidAddColumnDefault => {
2408 diagnostic_code::SchemaDdlAdmissionCode::InvalidAddColumnDefault
2409 }
2410 Self::InvalidAlterColumnDefault => {
2411 diagnostic_code::SchemaDdlAdmissionCode::InvalidAlterColumnDefault
2412 }
2413 Self::GeneratedIndexDropRejected => {
2414 diagnostic_code::SchemaDdlAdmissionCode::GeneratedIndexDropRejected
2415 }
2416 Self::SchemaRewriteRequiresMigration => {
2417 diagnostic_code::SchemaDdlAdmissionCode::SchemaRewriteRequiresMigration
2418 }
2419 Self::SchemaTransitionBudgetExceeded { .. } => {
2420 diagnostic_code::SchemaDdlAdmissionCode::SchemaTransitionBudgetExceeded
2421 }
2422 Self::GeneratedFieldDefaultChangeRejected => {
2423 diagnostic_code::SchemaDdlAdmissionCode::GeneratedFieldDefaultChangeRejected
2424 }
2425 Self::GeneratedFieldNullabilityChangeRejected => {
2426 diagnostic_code::SchemaDdlAdmissionCode::GeneratedFieldNullabilityChangeRejected
2427 }
2428 Self::RowLayoutVersionExhausted => {
2429 diagnostic_code::SchemaDdlAdmissionCode::RowLayoutVersionExhausted
2430 }
2431 }
2432 }
2433}
2434
2435#[repr(u8)]
2442#[derive(Clone, Copy, Eq, PartialEq)]
2443pub enum ErrorClass {
2444 Corruption,
2445 IncompatiblePersistedFormat,
2446 NotFound,
2447 Internal,
2448 Conflict,
2449 Unsupported,
2450 InvariantViolation,
2451}
2452
2453impl ErrorClass {
2454 #[must_use]
2456 pub const fn diagnostic_code(self, origin: ErrorOrigin) -> diagnostic_code::DiagnosticCode {
2457 match self {
2458 Self::Corruption if matches!(origin, ErrorOrigin::Store) => {
2459 diagnostic_code::DiagnosticCode::StoreCorruption
2460 }
2461 Self::Corruption => diagnostic_code::DiagnosticCode::RuntimeCorruption,
2462 Self::IncompatiblePersistedFormat => {
2463 diagnostic_code::DiagnosticCode::RuntimeIncompatiblePersistedFormat
2464 }
2465 Self::NotFound if matches!(origin, ErrorOrigin::Store) => {
2466 diagnostic_code::DiagnosticCode::StoreNotFound
2467 }
2468 Self::NotFound => diagnostic_code::DiagnosticCode::RuntimeNotFound,
2469 Self::Internal => diagnostic_code::DiagnosticCode::RuntimeInternal,
2470 Self::Conflict => diagnostic_code::DiagnosticCode::RuntimeConflict,
2471 Self::Unsupported if matches!(origin, ErrorOrigin::Cursor) => {
2472 diagnostic_code::DiagnosticCode::QueryInvalidContinuationCursor
2473 }
2474 Self::Unsupported => diagnostic_code::DiagnosticCode::RuntimeUnsupported,
2475 Self::InvariantViolation if matches!(origin, ErrorOrigin::Store) => {
2476 diagnostic_code::DiagnosticCode::StoreInvariantViolation
2477 }
2478 Self::InvariantViolation => diagnostic_code::DiagnosticCode::RuntimeInvariantViolation,
2479 }
2480 }
2481}
2482
2483impl fmt::Debug for ErrorClass {
2484 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2485 write!(f, "{}", *self as u8)
2486 }
2487}
2488
2489#[repr(u8)]
2496#[derive(Clone, Copy, Eq, PartialEq)]
2497pub enum ErrorOrigin {
2498 Serialize,
2499 Store,
2500 Index,
2501 Identity,
2502 Query,
2503 Planner,
2504 Cursor,
2505 Recovery,
2506 Response,
2507 Executor,
2508 Interface,
2509}
2510
2511impl ErrorOrigin {
2512 #[must_use]
2514 pub const fn diagnostic_origin(self) -> diagnostic_code::ErrorOrigin {
2515 match self {
2516 Self::Serialize => diagnostic_code::ErrorOrigin::Serialize,
2517 Self::Store => diagnostic_code::ErrorOrigin::Store,
2518 Self::Index => diagnostic_code::ErrorOrigin::Index,
2519 Self::Identity => diagnostic_code::ErrorOrigin::Identity,
2520 Self::Query => diagnostic_code::ErrorOrigin::Query,
2521 Self::Planner => diagnostic_code::ErrorOrigin::Planner,
2522 Self::Cursor => diagnostic_code::ErrorOrigin::Cursor,
2523 Self::Recovery => diagnostic_code::ErrorOrigin::Recovery,
2524 Self::Response => diagnostic_code::ErrorOrigin::Response,
2525 Self::Executor => diagnostic_code::ErrorOrigin::Executor,
2526 Self::Interface => diagnostic_code::ErrorOrigin::Interface,
2527 }
2528 }
2529}
2530
2531impl fmt::Debug for ErrorOrigin {
2532 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2533 write!(f, "{}", *self as u8)
2534 }
2535}