Skip to main content

graphrecords_python/querying/
exception.rs

1use graphrecords_core::{
2    errors::GraphRecordError as CoreGraphRecordError,
3    graphrecord::{GraphRecordValue, NodeIndex},
4};
5use graphrecords_query::{
6    Diagnostic, External, Failure,
7    error::{
8        aggregation::{InvalidMedianValue, InvalidStandardDeviationValue, InvalidVarianceValue},
9        argument::ArgumentAbsent,
10        arithmetic::{DivisionByZero, ModuloByZero},
11        comparison::{IncomparableValues, IncomparableValuesAt},
12        conversion::{InvalidCast, InvalidTransition},
13        dispatch::{OperationNotApplicable, UnsupportedValueRole},
14        execution::EvaluationCacheGraphRecordMismatch,
15        grouping::{
16            InvalidPartitionBucketArity, MissingGroupAggregate, UnresolvedBucketFailures,
17            UnresolvedGroupKeyFailures,
18        },
19        index::{DuplicateExpandedChildIndex, DuplicateIndex, NoChildIndex},
20        numeric::{
21            IntegerOverflow, InvalidClipBounds, NegativeLength, NegativeSquareRoot,
22            NonIntegerValue, NonNumericValue, NonPositiveLogarithm,
23        },
24        ordering::IncomparableIndices,
25        string::{
26            EmptySplitDelimiter, InvalidPaddingCharacter, InvalidRegexPattern, InvalidStringSlice,
27            NonStringValue, StringLengthOverflow, StringPaddingOverflow,
28        },
29        structure::{MissingAttribute, MissingTraversedAttribute},
30    },
31};
32use pyo3::{
33    create_exception,
34    exceptions::{PyException, PyTypeError},
35    prelude::*,
36};
37
38create_exception!(
39    graphrecords,
40    QueryError,
41    PyException,
42    "Base class for every graphrecords query diagnostic."
43);
44
45create_exception!(graphrecords, InvalidMedianValueError, QueryError);
46create_exception!(graphrecords, InvalidStandardDeviationValueError, QueryError);
47create_exception!(graphrecords, InvalidVarianceValueError, QueryError);
48create_exception!(graphrecords, ArgumentAbsentError, QueryError);
49create_exception!(graphrecords, DivisionByZeroError, QueryError);
50create_exception!(graphrecords, ModuloByZeroError, QueryError);
51create_exception!(graphrecords, IncomparableValuesError, QueryError);
52create_exception!(graphrecords, IncomparableValuesAtError, QueryError);
53create_exception!(graphrecords, InvalidCastError, QueryError);
54create_exception!(graphrecords, InvalidTransitionError, QueryError);
55create_exception!(graphrecords, UnsupportedValueRoleError, QueryError);
56create_exception!(
57    graphrecords,
58    EvaluationCacheGraphRecordMismatchError,
59    QueryError
60);
61create_exception!(graphrecords, InvalidPartitionBucketArityError, QueryError);
62create_exception!(graphrecords, MissingGroupAggregateError, QueryError);
63create_exception!(graphrecords, UnresolvedBucketFailuresError, QueryError);
64create_exception!(graphrecords, UnresolvedGroupKeyFailuresError, QueryError);
65create_exception!(graphrecords, DuplicateExpandedChildIndexError, QueryError);
66create_exception!(graphrecords, DuplicateIndexError, QueryError);
67create_exception!(graphrecords, NoChildIndexError, QueryError);
68create_exception!(graphrecords, IntegerOverflowError, QueryError);
69create_exception!(graphrecords, InvalidClipBoundsError, QueryError);
70create_exception!(graphrecords, NegativeLengthError, QueryError);
71create_exception!(graphrecords, NegativeSquareRootError, QueryError);
72create_exception!(graphrecords, NonIntegerValueError, QueryError);
73create_exception!(graphrecords, NonNumericValueError, QueryError);
74create_exception!(graphrecords, NonPositiveLogarithmError, QueryError);
75create_exception!(graphrecords, IncomparableIndicesError, QueryError);
76create_exception!(graphrecords, EmptySplitDelimiterError, QueryError);
77create_exception!(graphrecords, InvalidPaddingCharacterError, QueryError);
78create_exception!(graphrecords, InvalidRegexPatternError, QueryError);
79create_exception!(graphrecords, InvalidStringSliceError, QueryError);
80create_exception!(graphrecords, NonStringValueError, QueryError);
81create_exception!(graphrecords, StringLengthOverflowError, QueryError);
82create_exception!(graphrecords, StringPaddingOverflowError, QueryError);
83create_exception!(graphrecords, MissingAttributeError, QueryError);
84create_exception!(graphrecords, MissingTraversedAttributeError, QueryError);
85create_exception!(graphrecords, ExternalError, QueryError);
86create_exception!(graphrecords, GraphRecordError, QueryError);
87
88pub trait FailureConversion {
89    fn to_python_error(&self) -> PyErr;
90
91    fn to_python(&self, py: Python<'_>) -> Py<PyAny>;
92}
93
94impl FailureConversion for Failure {
95    fn to_python_error(&self) -> PyErr {
96        let message = self.to_string();
97
98        match self.kind().name() {
99            name if name == <InvalidMedianValue>::name() => {
100                InvalidMedianValueError::new_err(message)
101            }
102            name if name == <InvalidStandardDeviationValue>::name() => {
103                InvalidStandardDeviationValueError::new_err(message)
104            }
105            name if name == <InvalidVarianceValue>::name() => {
106                InvalidVarianceValueError::new_err(message)
107            }
108            name if name == <ArgumentAbsent>::name() => ArgumentAbsentError::new_err(message),
109            name if name == <DivisionByZero>::name() => DivisionByZeroError::new_err(message),
110            name if name == <ModuloByZero>::name() => ModuloByZeroError::new_err(message),
111            name if name == <IncomparableValues<GraphRecordValue>>::name() => {
112                IncomparableValuesError::new_err(message)
113            }
114            name if name == <IncomparableValuesAt<GraphRecordValue, NodeIndex>>::name() => {
115                IncomparableValuesAtError::new_err(message)
116            }
117            name if name == <InvalidCast<GraphRecordValue>>::name() => {
118                InvalidCastError::new_err(message)
119            }
120            name if name == <InvalidTransition<GraphRecordValue>>::name() => {
121                InvalidTransitionError::new_err(message)
122            }
123            name if name == <UnsupportedValueRole>::name() => {
124                UnsupportedValueRoleError::new_err(message)
125            }
126            name if name == <EvaluationCacheGraphRecordMismatch>::name() => {
127                EvaluationCacheGraphRecordMismatchError::new_err(message)
128            }
129            name if name == <InvalidPartitionBucketArity>::name() => {
130                InvalidPartitionBucketArityError::new_err(message)
131            }
132            name if name == <MissingGroupAggregate>::name() => {
133                MissingGroupAggregateError::new_err(message)
134            }
135            name if name == <UnresolvedBucketFailures>::name() => {
136                UnresolvedBucketFailuresError::new_err(message)
137            }
138            name if name == <UnresolvedGroupKeyFailures>::name() => {
139                UnresolvedGroupKeyFailuresError::new_err(message)
140            }
141            name if name == <DuplicateExpandedChildIndex<NodeIndex>>::name() => {
142                DuplicateExpandedChildIndexError::new_err(message)
143            }
144            name if name == <DuplicateIndex<NodeIndex>>::name() => {
145                DuplicateIndexError::new_err(message)
146            }
147            name if name == <NoChildIndex<NodeIndex>>::name() => {
148                NoChildIndexError::new_err(message)
149            }
150            name if name == <IntegerOverflow<GraphRecordValue>>::name() => {
151                IntegerOverflowError::new_err(message)
152            }
153            name if name == <InvalidClipBounds<GraphRecordValue>>::name() => {
154                InvalidClipBoundsError::new_err(message)
155            }
156            name if name == <NegativeLength>::name() => NegativeLengthError::new_err(message),
157            name if name == <NegativeSquareRoot>::name() => {
158                NegativeSquareRootError::new_err(message)
159            }
160            name if name == <NonIntegerValue<GraphRecordValue>>::name() => {
161                NonIntegerValueError::new_err(message)
162            }
163            name if name == <NonNumericValue<GraphRecordValue>>::name() => {
164                NonNumericValueError::new_err(message)
165            }
166            name if name == <NonPositiveLogarithm>::name() => {
167                NonPositiveLogarithmError::new_err(message)
168            }
169            name if name == <IncomparableIndices<GraphRecordValue, NodeIndex>>::name() => {
170                IncomparableIndicesError::new_err(message)
171            }
172            name if name == <EmptySplitDelimiter>::name() => {
173                EmptySplitDelimiterError::new_err(message)
174            }
175            name if name == <InvalidPaddingCharacter>::name() => {
176                InvalidPaddingCharacterError::new_err(message)
177            }
178            name if name == <InvalidRegexPattern>::name() => {
179                InvalidRegexPatternError::new_err(message)
180            }
181            name if name == <InvalidStringSlice>::name() => {
182                InvalidStringSliceError::new_err(message)
183            }
184            name if name == <NonStringValue<GraphRecordValue>>::name() => {
185                NonStringValueError::new_err(message)
186            }
187            name if name == <StringLengthOverflow>::name() => {
188                StringLengthOverflowError::new_err(message)
189            }
190            name if name == <StringPaddingOverflow>::name() => {
191                StringPaddingOverflowError::new_err(message)
192            }
193            name if name == <MissingAttribute>::name() => MissingAttributeError::new_err(message),
194            name if name == <MissingTraversedAttribute<NodeIndex>>::name() => {
195                MissingTraversedAttributeError::new_err(message)
196            }
197            name if name == <External<CoreGraphRecordError>>::name() => {
198                ExternalError::new_err(message)
199            }
200            name if name == <CoreGraphRecordError>::name() => GraphRecordError::new_err(message),
201            name if name == <OperationNotApplicable>::name() => PyTypeError::new_err(message),
202            _ => QueryError::new_err(message),
203        }
204    }
205
206    fn to_python(&self, py: Python<'_>) -> Py<PyAny> {
207        self.to_python_error().into_value(py).into_any()
208    }
209}