Skip to content

Commit 0f8708a

Browse files
committed
Updated error handling and changed broad Exception to specific errors
1 parent 1765cdd commit 0f8708a

15 files changed

+95
-54
lines changed

docs/source/changelog.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ Changelog
33

44
All notable changes to this project will be documented in this file.
55

6+
[0.3.1] - 2025-04-14
7+
--------------------
8+
9+
Changed
10+
^^^^^^^
11+
- Updated error handling and changed broad ``Exception`` to specific errors.
12+
- Smaller performance improvements
13+
14+
615
[0.3.0] - 2025-04-10
716
--------------------
817

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
project = "flask-inputfilter"
22
copyright = "2025, Leander Cain Slotosch"
33
author = "Leander Cain Slotosch"
4-
release = "0.3.0"
4+
release = "0.3.1"
55

66
extensions = ["sphinx_rtd_theme"]
77

docs/source/guides/create_own_components.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ Example implementation
149149
if value not in self.haystack:
150150
raise ValidationError
151151
152-
except Exception:
152+
except ValidationError:
153153
raise ValidationError(
154154
self.error_message
155155
or f"Value '{value}' is not in the allowed "

flask_inputfilter/Filter/Base64ImageDownscaleFilter.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import annotations
22

33
import base64
4+
import binascii
45
import io
56
from typing import Any, Optional
67

7-
from PIL import Image
8+
from PIL import Image, UnidentifiedImageError
89

910
from flask_inputfilter.Filter import BaseFilter
1011

@@ -38,7 +39,13 @@ def apply(self, value: Any) -> Any:
3839
image = Image.open(io.BytesIO(base64.b64decode(value)))
3940
return self.resize_picture(image)
4041

41-
except Exception:
42+
except (
43+
binascii.Error,
44+
UnidentifiedImageError,
45+
OSError,
46+
ValueError,
47+
TypeError,
48+
):
4249
return value
4350

4451
def resize_picture(self, image: Image) -> str:

flask_inputfilter/Filter/Base64ImageResizeFilter.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import annotations
22

33
import base64
4+
import binascii
45
import io
56
from typing import Any
67

7-
from PIL import Image
8+
from PIL import Image, UnidentifiedImageError
89

910
from flask_inputfilter.Enum import ImageFormatEnum
1011
from flask_inputfilter.Filter import BaseFilter
@@ -45,7 +46,13 @@ def apply(self, value: Any) -> Any:
4546

4647
value = Image.open(io.BytesIO(base64.b64decode(value)))
4748
return self.reduce_image(value)
48-
except Exception:
49+
except (
50+
binascii.Error,
51+
UnidentifiedImageError,
52+
OSError,
53+
ValueError,
54+
TypeError,
55+
):
4956
return value
5057

5158
def reduce_image(self, image: Image) -> Image:

flask_inputfilter/InputFilter.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import json
4+
import logging
45
from typing import (
56
Any,
67
Callable,
@@ -87,7 +88,7 @@ def isValid(self) -> bool:
8788
all required conditions; otherwise, returns False.
8889
"""
8990
try:
90-
self.validateData(self._data)
91+
self.validateData()
9192

9293
except ValidationError as e:
9394
self._errors = e.args[0]
@@ -133,9 +134,9 @@ def wrapper(
133134
validated_data = input_filter.validateData()
134135

135136
if input_filter._model_class is not None:
136-
validated_data = input_filter.serialize()
137-
138-
g.validated_data = validated_data
137+
g.validated_data = input_filter.serialize()
138+
else:
139+
g.validated_data = validated_data
139140

140141
except ValidationError as e:
141142
return Response(
@@ -144,6 +145,13 @@ def wrapper(
144145
mimetype="application/json",
145146
)
146147

148+
except Exception:
149+
logging.getLogger(__name__).exception(
150+
"An unexpected exception occurred while "
151+
"validating input data.",
152+
)
153+
return Response(status=500)
154+
147155
return f(*args, **kwargs)
148156

149157
return wrapper
@@ -175,7 +183,6 @@ def validateData(
175183
logical steps execution of the respective fields or conditions
176184
will propagate without explicit handling here.
177185
"""
178-
validated_data = self._validated_data
179186
data = data or self._data
180187
errors = {}
181188

@@ -193,11 +200,11 @@ def validateData(
193200

194201
try:
195202
if copy:
196-
value = validated_data.get(copy)
203+
value = self._validated_data.get(copy)
197204

198205
if external_api:
199206
value = self._ExternalApiMixin__callExternalApi(
200-
external_api, fallback, validated_data
207+
external_api, fallback, self._validated_data
201208
)
202209

203210
value = self._FilterMixin__applyFilters(filters, value)
@@ -215,18 +222,17 @@ def validateData(
215222
field_name, required, default, fallback, value
216223
)
217224

218-
validated_data[field_name] = value
225+
self._validated_data[field_name] = value
219226

220227
except ValidationError as e:
221228
errors[field_name] = str(e)
222229

223230
try:
224-
self._ConditionMixin__checkConditions(validated_data)
231+
self._ConditionMixin__checkConditions(self._validated_data)
225232
except ValidationError as e:
226233
errors["_condition"] = str(e)
227234

228235
if errors:
229236
raise ValidationError(errors)
230237

231-
self._validated_data = validated_data
232-
return validated_data
238+
return self._validated_data

flask_inputfilter/Mixin/DataMixin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ def hasUnknown(self) -> bool:
155155
"""
156156
if not self._data and self._fields:
157157
return True
158+
158159
return any(
159160
field_name not in self._fields.keys()
160161
for field_name in self._data.keys()

flask_inputfilter/Mixin/ExternalApiMixin.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,37 @@ def __callExternalApi(
8181

8282
try:
8383
response = requests.request(**requestData)
84-
85-
if response.status_code != 200:
86-
logger.error(
87-
f"External_api request inside of InputFilter "
88-
f"failed: {response.text}"
89-
)
90-
raise
91-
9284
result = response.json()
93-
94-
if data_key:
95-
return result.get(data_key)
96-
97-
return result
98-
except Exception:
85+
except requests.exceptions.RequestException:
86+
if fallback is None:
87+
logger.exception("External API request failed unexpectedly.")
88+
raise ValidationError(
89+
f"External API call failed for field " f"'{data_key}'."
90+
)
91+
return fallback
92+
except ValueError:
9993
if fallback is None:
94+
logger.exception(
95+
"External API response could not be parsed to json."
96+
)
10097
raise ValidationError(
10198
f"External API call failed for field " f"'{data_key}'."
10299
)
100+
return fallback
103101

102+
if response.status_code != 200:
103+
if fallback is None:
104+
logger.error(
105+
f"External API request failed with status "
106+
f"{response.status_code}: {response.text}"
107+
)
108+
raise ValidationError(
109+
f"External API call failed for field " f"'{data_key}'."
110+
)
104111
return fallback
105112

113+
return result.get(data_key) if data_key else result
114+
106115
@staticmethod
107116
def __replacePlaceholders(value: str, validated_data: dict) -> str:
108117
"""

flask_inputfilter/Mixin/ModelMixin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def merge(self, other: "InputFilter") -> None:
5555
for key, new_field in other.getInputs().items():
5656
self._fields[key] = new_field
5757

58-
self._conditions = self._conditions + other._conditions
58+
self._conditions += other._conditions
5959

6060
for filter in other._global_filters:
6161
existing_type_map = {

flask_inputfilter/Validator/InArrayValidator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def validate(self, value: Any) -> None:
3535
if value not in self.haystack:
3636
raise ValidationError
3737

38-
except Exception:
38+
except ValidationError:
3939
raise ValidationError(
4040
self.error_message
4141
or f"Value '{value}' is not in the allowed "

0 commit comments

Comments
 (0)