Skip to content

Commit

Permalink
✨ Improve error messages for URL validation
Browse files Browse the repository at this point in the history
Resolves #2243

Signed-off-by: ff137 <[email protected]>
  • Loading branch information
ff137 committed Oct 18, 2024
1 parent 90637c2 commit 67142cf
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/marshmallow/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from abc import ABC, abstractmethod
from itertools import zip_longest
from operator import attrgetter
from urllib.parse import urlparse

from marshmallow import types
from marshmallow.exceptions import ValidationError
Expand Down Expand Up @@ -210,11 +211,32 @@ def __call__(self, value: str) -> str:
if "://" in value:
scheme = value.split("://")[0].lower()
if scheme not in self.schemes:
raise ValidationError(message)
raise ValidationError(
f"Invalid URL scheme '{scheme}'. "
f"Allowed schemes are: {', '.join(self.schemes)}."
)

regex = self._regex(self.relative, self.absolute, self.require_tld)

if not regex.search(value):
if self.require_tld:
try:
# Extract the netloc (hostname and port)
parsed_url = urlparse(value)
hostname = parsed_url.hostname
except (ValueError, TypeError, AttributeError):
hostname = None

if hostname:
# Check if hostname is an IP address
is_ip = re.match(r"\d+\.\d+\.\d+\.\d+", hostname)
# Check if hostname contains a dot (.)
has_tld = "." in hostname
if not is_ip and not has_tld:
raise ValidationError(
"URL must include a top-level domain (e.g., '.com', '.org')."
)
# Default error message for other failures
raise ValidationError(message)

return value
Expand Down

0 comments on commit 67142cf

Please sign in to comment.