Skip to content

Commit

Permalink
Merge pull request #551 from azmeuk/issue-445
Browse files Browse the repository at this point in the history
Validators correctly raise exceptions
  • Loading branch information
azmeuk authored Apr 21, 2020
2 parents 129040a + 41731db commit a3f87bc
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ Unreleased
- form.errors is not cached and will update if an error is appended to a field after access. (:pr:`568`)
- :class:`~wtforms.validators.NumberRange` correctly handle *not a number*
values. (:pr:`505`, :pr:`548`)
- :class:`ValueError` raised by a validator are handled like regular exceptions. validators
need to raise :class:`~wtforms.validators.ValidationError` or
:class:`~wtforms.validators.StopValidation` to make a validation fail (:pr:`445`, :pr:`551`).


Version 2.2.1
Expand Down
12 changes: 6 additions & 6 deletions src/wtforms/fields/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from wtforms.compat import izip, text_type
from wtforms.i18n import DummyTranslations
from wtforms.utils import unset_value
from wtforms.validators import StopValidation
from wtforms.validators import StopValidation, ValidationError

__all__ = (
"BooleanField",
Expand Down Expand Up @@ -246,7 +246,7 @@ def validate(self, form, extra_validators=()):
if e.args and e.args[0]:
self.errors.append(e.args[0])
stop_validation = True
except ValueError as e:
except ValidationError as e:
self.errors.append(e.args[0])

# Run validators
Expand All @@ -257,7 +257,7 @@ def validate(self, form, extra_validators=()):
# Call post_validate
try:
self.post_validate(form, stop_validation)
except ValueError as e:
except ValidationError as e:
self.errors.append(e.args[0])

return len(self.errors) == 0
Expand All @@ -277,7 +277,7 @@ def _run_validation_chain(self, form, validators):
if e.args and e.args[0]:
self.errors.append(e.args[0])
return True
except ValueError as e:
except ValidationError as e:
self.errors.append(e.args[0])

return False
Expand Down Expand Up @@ -553,7 +553,7 @@ def pre_validate(self, form):
if self.data == v:
break
else:
raise ValueError(self.gettext("Not a valid choice"))
raise ValidationError(self.gettext("Not a valid choice"))


class SelectMultipleField(SelectField):
Expand Down Expand Up @@ -591,7 +591,7 @@ def pre_validate(self, form):
values = list(c[0] for c in self.choices)
for d in self.data:
if d not in values:
raise ValueError(
raise ValidationError(
self.gettext("'%(value)s' is not a valid choice for this field")
% dict(value=d)
)
Expand Down
8 changes: 4 additions & 4 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ def pre_validate(self, form):

def post_validate(self, form, stopped):
if self.data == "p":
raise ValueError("Post")
raise validators.ValidationError("Post")
elif stopped and self.data == "stop-post":
raise ValueError("Post-stopped")
raise validators.ValidationError("Post-stopped")


class TestPrePostValidation:
Expand Down Expand Up @@ -1002,9 +1002,9 @@ def test_min_max_entries(self):
def test_validators(self):
def validator(form, field):
if field.data and field.data[0] == "fail":
raise ValueError("fail")
raise validators.ValidationError("fail")
elif len(field.data) > 2:
raise ValueError("too many")
raise validators.ValidationError("too many")

F = make_form(a=FieldList(self.t, validators=[validator]))

Expand Down
16 changes: 15 additions & 1 deletion tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest
import re

from wtforms import Label
from wtforms import Label, Form, StringField
from wtforms.compat import text_type
from wtforms.validators import (
StopValidation,
Expand Down Expand Up @@ -670,3 +670,17 @@ def test_regexp_message(dummy_form, dummy_field, grab_error_message):
validator = regexp("^a", message="foo")
dummy_field.data = "f"
assert grab_error_message(validator, dummy_form, dummy_field) == "foo"


@pytest.mark.parametrize("exc", [IndexError, ZeroDivisionError, ValueError])
def test_raise_exceptions(exc):
def validate(form, field):
raise exc

class F(Form):
field = StringField(validators=[validate])

f = F()

with pytest.raises(exc):
f.validate()

0 comments on commit a3f87bc

Please # to comment.