Unify error messages under one banner

This commit is contained in:
zandercymatics 2024-01-09 11:41:55 -07:00
parent 02456e9297
commit 89431b111d
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
4 changed files with 107 additions and 58 deletions

View file

@ -1,7 +1,7 @@
"""Internal API views"""
from django.apps import apps
from django.views.decorators.http import require_http_methods
from django.http import HttpResponse, JsonResponse
from django.http import HttpResponse
from django.utils.safestring import mark_safe
from registrar.templatetags.url_helpers import public_site_url
@ -71,6 +71,7 @@ def check_domain_available(domain):
a match. If check fails, throws a RegistryError.
"""
Domain = apps.get_model("registrar.Domain")
if domain.endswith(".gov"):
return Domain.available(domain)
else:
@ -86,29 +87,15 @@ def available(request, domain=""):
Response is a JSON dictionary with the key "available" and value true or
false.
"""
Domain = apps.get_model("registrar.Domain")
domain = request.GET.get("domain", "")
DraftDomain = apps.get_model("registrar.DraftDomain")
if domain is None or domain.strip() == "":
# TODO - change this... should it be the regular required?
return JsonResponse({"available": False, "code": "invalid", "message": "This field is required"})
# validate that the given domain could be a domain name and fail early if
# not.
if not (DraftDomain.string_could_be_domain(domain) or DraftDomain.string_could_be_domain(domain + ".gov")):
print(f"What is the domain at this point? {domain}")
if "." in domain:
return JsonResponse({"available": False, "code": "invalid", "message": DOMAIN_API_MESSAGES["extra_dots"]})
else:
return JsonResponse({"available": False, "code": "invalid", "message": DOMAIN_API_MESSAGES["invalid"]})
# a domain is available if it is NOT in the list of current domains
try:
if check_domain_available(domain):
return JsonResponse({"available": True, "code": "success", "message": DOMAIN_API_MESSAGES["success"]})
else:
return JsonResponse(
{"available": False, "code": "unavailable", "message": DOMAIN_API_MESSAGES["unavailable"]}
json_response = Domain.validate_and_handle_errors(
domain=domain,
error_return_type="JSON_RESPONSE",
display_success=True,
)
except Exception:
return JsonResponse({"available": False, "code": "error", "message": DOMAIN_API_MESSAGES["error"]})
return json_response
@require_http_methods(["GET"])

View file

@ -384,17 +384,8 @@ CurrentSitesFormSet = forms.formset_factory(
class AlternativeDomainForm(RegistrarForm):
def clean_alternative_domain(self):
"""Validation code for domain names."""
try:
requested = self.cleaned_data.get("alternative_domain", None)
validated = DraftDomain.validate(requested, blank_ok=True)
except errors.ExtraDotsError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["extra_dots"], code="extra_dots")
except errors.DomainUnavailableError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["unavailable"], code="unavailable")
except errors.RegistrySystemError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["error"], code="error")
except ValueError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["invalid"], code="invalid")
validated = DraftDomain.validate_and_handle_errors(requested, "FORM_VALIDATION_ERROR")
return validated
alternative_domain = forms.CharField(
@ -469,19 +460,8 @@ class DotGovDomainForm(RegistrarForm):
def clean_requested_domain(self):
"""Validation code for domain names."""
try:
requested = self.cleaned_data.get("requested_domain", None)
validated = DraftDomain.validate(requested)
except errors.BlankValueError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["required"], code="required")
except errors.ExtraDotsError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["extra_dots"], code="extra_dots")
except errors.DomainUnavailableError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["unavailable"], code="unavailable")
except errors.RegistrySystemError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["error"], code="error")
except ValueError:
raise forms.ValidationError(DOMAIN_API_MESSAGES["invalid"], code="invalid")
validated = DraftDomain.validate_and_handle_errors(requested, "FORM_VALIDATION_ERROR")
return validated
requested_domain = forms.CharField(label="What .gov domain do you want?")

View file

@ -1,9 +1,16 @@
from enum import Enum
import re
from api.views import check_domain_available
from django import forms
from django.http import JsonResponse
from api.views import DOMAIN_API_MESSAGES, check_domain_available
from registrar.utility import errors
from epplibwrapper.errors import RegistryError
class ValidationErrorReturnType(Enum):
JSON_RESPONSE = "JSON_RESPONSE"
FORM_VALIDATION_ERROR = "FORM_VALIDATION_ERROR"
class DomainHelper:
"""Utility functions and constants for domain names."""
@ -28,16 +35,10 @@ class DomainHelper:
if domain is None:
raise errors.BlankValueError()
if not isinstance(domain, str):
raise ValueError("Domain name must be a string")
domain = domain.lower().strip()
if domain == "" and not blank_ok:
raise errors.BlankValueError()
if domain.endswith(".gov"):
domain = domain[:-4]
if "." in domain:
raise errors.ExtraDotsError()
if not DomainHelper.string_could_be_domain(domain + ".gov"):
raise ValueError()
raise errors.InvalidDomainError("Domain name must be a string")
domain = DomainHelper._parse_domain_string(domain, blank_ok)
try:
if not check_domain_available(domain):
raise errors.DomainUnavailableError()
@ -45,6 +46,85 @@ class DomainHelper:
raise errors.RegistrySystemError() from err
return domain
@staticmethod
def _parse_domain_string(domain: str, blank_ok) -> str:
"""Parses '.gov' out of the domain_name string, and does some validation on it"""
domain = domain.lower().strip()
if domain == "" and not blank_ok:
raise errors.BlankValueError()
if domain.endswith(".gov"):
domain = domain[:-4]
if "." in domain:
raise errors.ExtraDotsError()
if not DomainHelper.string_could_be_domain(domain + ".gov"):
raise errors.InvalidDomainError()
@classmethod
def validate_and_handle_errors(cls, domain: str, error_return_type: str, display_success: bool = False):
"""Runs validate() and catches possible exceptions."""
try:
validated = cls.validate(domain)
except errors.BlankValueError:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="required"
)
except errors.ExtraDotsError:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="extra_dots"
)
except errors.DomainUnavailableError:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="unavailable"
)
except errors.RegistrySystemError:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="error"
)
except errors.InvalidDomainError:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="invalid"
)
except Exception:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="error"
)
else:
if display_success:
return DomainHelper._return_form_error_or_json_response(
error_return_type, code="success", available=True
)
else:
return validated
@staticmethod
def _return_form_error_or_json_response(return_type, code, available=False):
print(f"What is the code? {code}")
if return_type == "JSON_RESPONSE":
print("in the return context")
return JsonResponse(
{"available": available, "code": code, "message": DOMAIN_API_MESSAGES[code]}
)
if return_type == "FORM_VALIDATION_ERROR":
raise forms.ValidationError(DOMAIN_API_MESSAGES[code], code=code)
# Why is this not working??
"""
match return_type:
case ValidationErrorReturnType.FORM_VALIDATION_ERROR:
raise forms.ValidationError(DOMAIN_API_MESSAGES[code], code=code)
case ValidationErrorReturnType.JSON_RESPONSE:
return JsonResponse(
{"available": available, "code": code, "message": DOMAIN_API_MESSAGES[code]}
)
case _:
raise ValueError("Invalid return type specified")
"""
@classmethod
def sld(cls, domain: str):
"""

View file

@ -16,6 +16,8 @@ class DomainUnavailableError(ValueError):
class RegistrySystemError(ValueError):
pass
class InvalidDomainError(ValueError):
pass
class ActionNotAllowed(Exception):
"""User accessed an action that is not