1
1
use std:: borrow:: Cow ;
2
2
use std:: str:: FromStr ;
3
3
4
- use pyo3:: exceptions:: { PyAttributeError , PyRuntimeError } ;
4
+ use pyo3:: exceptions:: { PyAttributeError , PyRecursionError , PyRuntimeError } ;
5
5
use pyo3:: intern;
6
6
use pyo3:: prelude:: * ;
7
7
use pyo3:: types:: PyDict ;
8
8
9
9
use pyo3:: types:: PyString ;
10
- use serde:: ser:: Error ;
11
10
12
- use crate :: build_tools:: { function_name, py_error_type, SchemaDict } ;
11
+ use crate :: build_tools:: { function_name, py_err , py_error_type, SchemaDict } ;
13
12
use crate :: definitions:: DefinitionsBuilder ;
14
13
use crate :: { PydanticOmit , PydanticSerializationUnexpectedValue } ;
15
14
@@ -154,6 +153,26 @@ impl FunctionPlainSerializer {
154
153
}
155
154
}
156
155
156
+ fn on_error ( py : Python , err : PyErr , function_name : & str , extra : & Extra ) -> PyResult < ( ) > {
157
+ let exception = err. value ( py) ;
158
+ if let Ok ( ser_err) = exception. extract :: < PydanticSerializationUnexpectedValue > ( ) {
159
+ if extra. check . enabled ( ) {
160
+ Err ( err)
161
+ } else {
162
+ extra. warnings . custom_warning ( ser_err. __repr__ ( ) ) ;
163
+ Ok ( ( ) )
164
+ }
165
+ } else if let Ok ( err) = exception. extract :: < PydanticSerializationError > ( ) {
166
+ py_err ! ( PydanticSerializationError ; "{}" , err)
167
+ } else if exception. is_instance_of :: < PyRecursionError > ( ) . unwrap_or ( false ) {
168
+ py_err ! ( PydanticSerializationError ; "Error calling function `{}`: RecursionError" , function_name)
169
+ } else {
170
+ let new_err = py_error_type ! ( PydanticSerializationError ; "Error calling function `{}`: {}" , function_name, err) ;
171
+ new_err. set_cause ( py, Some ( err) ) ;
172
+ Err ( new_err)
173
+ }
174
+ }
175
+
157
176
macro_rules! function_type_serializer {
158
177
( $name: ident) => {
159
178
impl TypeSerializer for $name {
@@ -177,21 +196,10 @@ macro_rules! function_type_serializer {
177
196
_ => Ok ( next_value. to_object( py) ) ,
178
197
}
179
198
}
180
- Err ( err) => match err. value( py) . extract:: <PydanticSerializationUnexpectedValue >( ) {
181
- Ok ( ser_err) => {
182
- if extra. check. enabled( ) {
183
- Err ( err)
184
- } else {
185
- extra. warnings. custom_warning( ser_err. __repr__( ) ) ;
186
- infer_to_python( value, include, exclude, extra)
187
- }
188
- }
189
- Err ( _) => {
190
- let new_err = py_error_type!( PydanticSerializationError ; "Error calling function `{}`: {}" , self . function_name, err) ;
191
- new_err. set_cause( py, Some ( err) ) ;
192
- Err ( new_err)
193
- }
194
- } ,
199
+ Err ( err) => {
200
+ on_error( py, err, & self . function_name, extra) ?;
201
+ infer_to_python( value, include, exclude, extra)
202
+ }
195
203
}
196
204
}
197
205
@@ -205,21 +213,10 @@ macro_rules! function_type_serializer {
205
213
None => infer_json_key( next_key, extra) ,
206
214
}
207
215
}
208
- Err ( err) => match err. value( py) . extract:: <PydanticSerializationUnexpectedValue >( ) {
209
- Ok ( ser_err) => {
210
- if extra. check. enabled( ) {
211
- Err ( err)
212
- } else {
213
- extra. warnings. custom_warning( ser_err. __repr__( ) ) ;
214
- infer_json_key( key, extra)
215
- }
216
- }
217
- Err ( _) => {
218
- let new_err = py_error_type!( PydanticSerializationError ; "Error calling function `{}`: {}" , self . function_name, err) ;
219
- new_err. set_cause( py, Some ( err) ) ;
220
- Err ( new_err)
221
- }
222
- } ,
216
+ Err ( err) => {
217
+ on_error( py, err, & self . function_name, extra) ?;
218
+ infer_json_key( key, extra)
219
+ }
223
220
}
224
221
}
225
222
@@ -235,28 +232,18 @@ macro_rules! function_type_serializer {
235
232
match self . call( value, include, exclude, extra) {
236
233
Ok ( v) => {
237
234
let next_value = v. as_ref( py) ;
238
- // None for include/exclude here, as filtering should be done
235
+ // None for include/exclude here, as filtering should be done
239
236
match self . json_return_ob_type {
240
237
Some ( ref ob_type) => {
241
238
infer_serialize_known( ob_type, next_value, serializer, None , None , extra)
242
239
}
243
240
None => infer_serialize( next_value, serializer, None , None , extra) ,
244
241
}
245
242
}
246
- Err ( err) => match err. value( py) . extract:: <PydanticSerializationUnexpectedValue >( ) {
247
- Ok ( ser_err) => {
248
- if extra. check. enabled( ) {
249
- Err ( py_err_se_err( err) )
250
- } else {
251
- extra. warnings. custom_warning( ser_err. __repr__( ) ) ;
252
- infer_serialize( value, serializer, include, exclude, extra)
253
- }
254
- }
255
- Err ( _) => Err ( Error :: custom( format!(
256
- "Error calling function `{}`: {}" ,
257
- self . function_name, err
258
- ) ) ) ,
259
- } ,
243
+ Err ( err) => {
244
+ on_error( py, err, & self . function_name, extra) . map_err( py_err_se_err) ?;
245
+ infer_serialize( value, serializer, include, exclude, extra)
246
+ }
260
247
}
261
248
}
262
249
0 commit comments