|
8 | 8 | from typing import get_origin |
9 | 9 | from functools import wraps |
10 | 10 |
|
| 11 | +from flask import jsonify |
11 | 12 | from flask import request |
| 13 | +from flask import current_app |
| 14 | +from flask import make_response |
12 | 15 | from werkzeug.exceptions import BadRequest |
13 | 16 | from werkzeug.exceptions import UnsupportedMediaType |
14 | 17 |
|
15 | 18 | from flask_utils.errors import BadRequestError |
16 | 19 |
|
17 | | -# TODO: Change validate_params to either use BadRequestError or just return a 400 depending |
18 | | -# on if the error handler is registered or not in the FlaskUtils class |
19 | | - |
20 | 20 | VALIDATE_PARAMS_MAX_DEPTH = 4 |
21 | 21 |
|
22 | 22 |
|
@@ -236,41 +236,125 @@ def example(): |
236 | 236 | * Optional |
237 | 237 | * Union |
238 | 238 |
|
| 239 | + .. versionchanged:: 0.7.0 |
| 240 | + The decorator will now use the custom error handlers if ``register_error_handlers`` has been set to ``True`` |
| 241 | + when initializing the :class:`~flask_utils.extension.FlaskUtils` extension. |
| 242 | +
|
239 | 243 | .. versionadded:: 0.2.0 |
240 | 244 | """ |
241 | 245 |
|
242 | 246 | def decorator(fn): # type: ignore |
243 | 247 | @wraps(fn) |
244 | 248 | def wrapper(*args, **kwargs): # type: ignore |
| 249 | + use_error_handlers = False |
| 250 | + if current_app.extensions.get("flask_utils") is not None: |
| 251 | + if current_app.extensions["flask_utils"].has_error_handlers_registered: |
| 252 | + use_error_handlers = True |
| 253 | + |
245 | 254 | try: |
246 | 255 | data = request.get_json() |
247 | 256 | except BadRequest as e: |
248 | | - raise BadRequestError("The Json Body is malformed.") from e |
| 257 | + if use_error_handlers: |
| 258 | + raise BadRequestError("The Json Body is malformed.") from e |
| 259 | + else: |
| 260 | + return make_response( |
| 261 | + jsonify( |
| 262 | + { |
| 263 | + "error": "The Json Body is malformed.", |
| 264 | + } |
| 265 | + ), |
| 266 | + 400, |
| 267 | + ) |
249 | 268 | except UnsupportedMediaType as e: |
250 | | - raise BadRequestError( |
251 | | - "The Content-Type header is missing or is not set to application/json, or the JSON body is missing." |
252 | | - ) from e |
| 269 | + if use_error_handlers: |
| 270 | + raise BadRequestError( |
| 271 | + "The Content-Type header is missing or is not set to application/json, " |
| 272 | + "or the JSON body is missing." |
| 273 | + ) from e |
| 274 | + else: |
| 275 | + return make_response( |
| 276 | + jsonify( |
| 277 | + { |
| 278 | + "error": "The Content-Type header is missing or is not set to application/json, " |
| 279 | + "or the JSON body is missing.", |
| 280 | + } |
| 281 | + ), |
| 282 | + 400, |
| 283 | + ) |
253 | 284 |
|
254 | 285 | if not data: |
255 | | - raise BadRequestError("Missing json body.") |
| 286 | + if use_error_handlers: |
| 287 | + raise BadRequestError("Missing json body.") |
| 288 | + else: |
| 289 | + return make_response( |
| 290 | + jsonify( |
| 291 | + { |
| 292 | + "error": "Missing json body.", |
| 293 | + } |
| 294 | + ), |
| 295 | + 400, |
| 296 | + ) |
256 | 297 |
|
257 | 298 | if not isinstance(data, dict): |
258 | | - raise BadRequestError("JSON body must be a dict") |
| 299 | + if use_error_handlers: |
| 300 | + raise BadRequestError("JSON body must be a dict") |
| 301 | + else: |
| 302 | + return make_response( |
| 303 | + jsonify( |
| 304 | + { |
| 305 | + "error": "JSON body must be a dict", |
| 306 | + } |
| 307 | + ), |
| 308 | + 400, |
| 309 | + ) |
259 | 310 |
|
260 | 311 | for key, type_hint in parameters.items(): |
261 | 312 | if not _is_optional(type_hint) and key not in data: |
262 | | - raise BadRequestError(f"Missing key: {key}", f"Expected keys are: {parameters.keys()}") |
| 313 | + if use_error_handlers: |
| 314 | + raise BadRequestError(f"Missing key: {key}", f"Expected keys are: {parameters.keys()}") |
| 315 | + else: |
| 316 | + return make_response( |
| 317 | + jsonify( |
| 318 | + { |
| 319 | + "error": f"Missing key: {key}", |
| 320 | + "expected_keys": parameters.keys(), |
| 321 | + } |
| 322 | + ), |
| 323 | + 400, |
| 324 | + ) |
263 | 325 |
|
264 | 326 | for key in data: |
265 | 327 | if key not in parameters: |
266 | | - raise BadRequestError( |
267 | | - f"Unexpected key: {key}.", |
268 | | - f"Expected keys are: {parameters.keys()}", |
269 | | - ) |
| 328 | + if use_error_handlers: |
| 329 | + raise BadRequestError( |
| 330 | + f"Unexpected key: {key}.", |
| 331 | + f"Expected keys are: {parameters.keys()}", |
| 332 | + ) |
| 333 | + else: |
| 334 | + return make_response( |
| 335 | + jsonify( |
| 336 | + { |
| 337 | + "error": f"Unexpected key: {key}.", |
| 338 | + "expected_keys": parameters.keys(), |
| 339 | + } |
| 340 | + ), |
| 341 | + 400, |
| 342 | + ) |
270 | 343 |
|
271 | 344 | for key in data: |
272 | 345 | if key in parameters and not _check_type(data[key], parameters[key], allow_empty): |
273 | | - raise BadRequestError(f"Wrong type for key {key}.", f"It should be {parameters[key]}") |
| 346 | + if use_error_handlers: |
| 347 | + raise BadRequestError(f"Wrong type for key {key}.", f"It should be {parameters[key]}") |
| 348 | + else: |
| 349 | + return make_response( |
| 350 | + jsonify( |
| 351 | + { |
| 352 | + "error": f"Wrong type for key {key}.", |
| 353 | + "expected_type": parameters[key], |
| 354 | + } |
| 355 | + ), |
| 356 | + 400, |
| 357 | + ) |
274 | 358 |
|
275 | 359 | return fn(*args, **kwargs) |
276 | 360 |
|
|
0 commit comments