icydb_core/db/query/intent/
errors.rs1use crate::{
2 db::{
3 cursor::CursorPlanError,
4 predicate::ValidateError,
5 query::plan::{
6 CursorPagingPolicyError, FluentLoadPolicyViolation, IntentKeyAccessPolicyViolation,
7 PlanError, PlannerError, PolicyPlanError,
8 },
9 response::ResponseError,
10 },
11 error::{ErrorClass, InternalError},
12};
13use thiserror::Error as ThisError;
14
15#[derive(Debug, ThisError)]
20pub enum QueryError {
21 #[error("{0}")]
22 Validate(#[from] ValidateError),
23
24 #[error("{0}")]
25 Plan(Box<PlanError>),
26
27 #[error("{0}")]
28 Intent(#[from] IntentError),
29
30 #[error("{0}")]
31 Response(#[from] ResponseError),
32
33 #[error("{0}")]
34 Execute(#[from] QueryExecuteError),
35}
36
37impl QueryError {
38 pub(crate) fn execute(err: InternalError) -> Self {
40 Self::Execute(QueryExecuteError::from(err))
41 }
42}
43
44#[derive(Debug, ThisError)]
49pub enum QueryExecuteError {
50 #[error("{0}")]
51 Corruption(InternalError),
52
53 #[error("{0}")]
54 InvariantViolation(InternalError),
55
56 #[error("{0}")]
57 Conflict(InternalError),
58
59 #[error("{0}")]
60 NotFound(InternalError),
61
62 #[error("{0}")]
63 Unsupported(InternalError),
64
65 #[error("{0}")]
66 Internal(InternalError),
67}
68
69impl QueryExecuteError {
70 #[must_use]
71 pub const fn as_internal(&self) -> &InternalError {
73 match self {
74 Self::Corruption(err)
75 | Self::InvariantViolation(err)
76 | Self::Conflict(err)
77 | Self::NotFound(err)
78 | Self::Unsupported(err)
79 | Self::Internal(err) => err,
80 }
81 }
82}
83
84impl From<InternalError> for QueryExecuteError {
85 fn from(err: InternalError) -> Self {
86 match err.class {
87 ErrorClass::Corruption => Self::Corruption(err),
88 ErrorClass::InvariantViolation => Self::InvariantViolation(err),
89 ErrorClass::Conflict => Self::Conflict(err),
90 ErrorClass::NotFound => Self::NotFound(err),
91 ErrorClass::Unsupported => Self::Unsupported(err),
92 ErrorClass::Internal => Self::Internal(err),
93 }
94 }
95}
96
97impl From<PlannerError> for QueryError {
98 fn from(err: PlannerError) -> Self {
99 match err {
100 PlannerError::Plan(err) => Self::from(*err),
101 PlannerError::Internal(err) => Self::execute(*err),
102 }
103 }
104}
105
106impl From<PlanError> for QueryError {
107 fn from(err: PlanError) -> Self {
108 Self::Plan(Box::new(err))
109 }
110}
111
112#[derive(Clone, Copy, Debug, ThisError)]
117pub enum IntentError {
118 #[error("{0}")]
119 PlanShape(#[from] PolicyPlanError),
120
121 #[error("by_ids() cannot be combined with predicates")]
122 ByIdsWithPredicate,
123
124 #[error("only() cannot be combined with predicates")]
125 OnlyWithPredicate,
126
127 #[error("multiple key access methods were used on the same query")]
128 KeyAccessConflict,
129
130 #[error(
131 "{message}",
132 message = CursorPlanError::cursor_requires_order_message()
133 )]
134 CursorRequiresOrder,
135
136 #[error(
137 "{message}",
138 message = CursorPlanError::cursor_requires_limit_message()
139 )]
140 CursorRequiresLimit,
141
142 #[error("cursor tokens can only be used with .page().execute()")]
143 CursorRequiresPagedExecution,
144
145 #[error("grouped queries require execute_grouped(...)")]
146 GroupedRequiresExecuteGrouped,
147
148 #[error("HAVING requires GROUP BY")]
149 HavingRequiresGroupBy,
150}
151
152impl From<CursorPagingPolicyError> for IntentError {
153 fn from(err: CursorPagingPolicyError) -> Self {
154 match err {
155 CursorPagingPolicyError::CursorRequiresOrder => Self::CursorRequiresOrder,
156 CursorPagingPolicyError::CursorRequiresLimit => Self::CursorRequiresLimit,
157 }
158 }
159}
160
161impl From<IntentKeyAccessPolicyViolation> for IntentError {
162 fn from(err: IntentKeyAccessPolicyViolation) -> Self {
163 match err {
164 IntentKeyAccessPolicyViolation::KeyAccessConflict => Self::KeyAccessConflict,
165 IntentKeyAccessPolicyViolation::ByIdsWithPredicate => Self::ByIdsWithPredicate,
166 IntentKeyAccessPolicyViolation::OnlyWithPredicate => Self::OnlyWithPredicate,
167 }
168 }
169}
170
171impl From<FluentLoadPolicyViolation> for IntentError {
172 fn from(err: FluentLoadPolicyViolation) -> Self {
173 match err {
174 FluentLoadPolicyViolation::CursorRequiresPagedExecution => {
175 Self::CursorRequiresPagedExecution
176 }
177 FluentLoadPolicyViolation::GroupedRequiresExecuteGrouped => {
178 Self::GroupedRequiresExecuteGrouped
179 }
180 FluentLoadPolicyViolation::CursorRequiresOrder => Self::CursorRequiresOrder,
181 FluentLoadPolicyViolation::CursorRequiresLimit => Self::CursorRequiresLimit,
182 }
183 }
184}