manage.get.gov/src/registrar/utility/errors.py
2024-06-25 15:29:52 -06:00

256 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from enum import IntEnum
class BlankValueError(ValueError):
pass
class ExtraDotsError(ValueError):
pass
class DomainUnavailableError(ValueError):
pass
class RegistrySystemError(ValueError):
pass
class InvalidDomainError(ValueError):
"""Error class for situations where an invalid domain is supplied"""
pass
class ActionNotAllowed(Exception):
"""User accessed an action that is not
allowed by the current state"""
pass
class GenericErrorCodes(IntEnum):
"""Used across the registrar for
error mapping.
Overview of generic error codes:
- 1 GENERIC_ERROR a generic value error
- 2 CANNOT_CONTACT_REGISTRY a connection error w registry
"""
GENERIC_ERROR = 1
CANNOT_CONTACT_REGISTRY = 2
class GenericError(Exception):
"""
GenericError class used to raise exceptions across
the registrar
"""
_error_mapping = {
GenericErrorCodes.CANNOT_CONTACT_REGISTRY: (
"Were experiencing a system error. Please wait a few minutes "
"and try again. If you continue to get this error, "
"contact help@get.gov."
),
GenericErrorCodes.GENERIC_ERROR: ("Value entered was wrong."),
}
def __init__(self, *args, code=None, **kwargs):
super().__init__(*args, **kwargs)
self.code = code
if self.code in self._error_mapping:
self.message = self._error_mapping.get(self.code)
def __str__(self):
return f"{self.message}"
@classmethod
def get_error_message(self, code=None):
return self._error_mapping.get(code)
class FSMErrorCodes(IntEnum):
"""Used when doing FSM transitions.
Overview of generic error codes:
- 1 APPROVE_DOMAIN_IN_USE The domain is already in use
- 2 NO_INVESTIGATOR No investigator is assigned
- 3 INVESTIGATOR_NOT_STAFF Investigator is a non-staff user
- 4 INVESTIGATOR_NOT_SUBMITTER The form submitter is not the investigator
- 5 NO_REJECTION_REASON No rejection reason is specified
- 6 NO_ACTION_NEEDED_REASON No action needed reason is specified
"""
APPROVE_DOMAIN_IN_USE = 1
NO_INVESTIGATOR = 2
INVESTIGATOR_NOT_STAFF = 3
INVESTIGATOR_NOT_SUBMITTER = 4
NO_REJECTION_REASON = 5
NO_ACTION_NEEDED_REASON = 6
class FSMDomainRequestError(Exception):
"""
Used to raise exceptions when doing FSM Transitions.
Uses `FSMErrorCodes` as an enum.
"""
_error_mapping = {
FSMErrorCodes.APPROVE_DOMAIN_IN_USE: ("Cannot approve. Requested domain is already in use."),
FSMErrorCodes.NO_INVESTIGATOR: ("Investigator is required for this status."),
FSMErrorCodes.INVESTIGATOR_NOT_STAFF: ("Investigator is not a staff user."),
FSMErrorCodes.INVESTIGATOR_NOT_SUBMITTER: ("Only the assigned investigator can make this change."),
FSMErrorCodes.NO_REJECTION_REASON: ("A reason is required for this status."),
FSMErrorCodes.NO_ACTION_NEEDED_REASON: ("A reason is required for this status."),
}
def __init__(self, *args, code=None, **kwargs):
super().__init__(*args, **kwargs)
self.code = code
if self.code in self._error_mapping:
self.message = self._error_mapping.get(self.code)
def __str__(self):
return f"{self.message}"
@classmethod
def get_error_message(cls, code=None):
return cls._error_mapping.get(code)
class NameserverErrorCodes(IntEnum):
"""Used in the NameserverError class for
error mapping.
Overview of nameserver error codes:
- 1 MISSING_IP ip address is missing for a nameserver
- 2 GLUE_RECORD_NOT_ALLOWED a host has a nameserver
value but is not a subdomain
- 3 INVALID_IP invalid ip address format or invalid version
- 4 TOO_MANY_HOSTS more than the max allowed host values
- 5 MISSING_HOST host is missing for a nameserver
- 6 INVALID_HOST host is invalid for a nameserver
- 7 DUPLICATE_HOST host is a duplicate
- 8 BAD_DATA bad data input for nameserver
"""
MISSING_IP = 1
GLUE_RECORD_NOT_ALLOWED = 2
INVALID_IP = 3
TOO_MANY_HOSTS = 4
MISSING_HOST = 5
INVALID_HOST = 6
DUPLICATE_HOST = 7
BAD_DATA = 8
class NameserverError(Exception):
"""
NameserverError class used to raise exceptions on
the nameserver getter
"""
_error_mapping = {
NameserverErrorCodes.MISSING_IP: ("Using your domain for a name server requires an IP address."),
NameserverErrorCodes.GLUE_RECORD_NOT_ALLOWED: ("Name server address does not match domain name"),
NameserverErrorCodes.INVALID_IP: ("{}: Enter an IP address in the required format."),
NameserverErrorCodes.TOO_MANY_HOSTS: ("You can't have more than 13 nameservers."),
NameserverErrorCodes.MISSING_HOST: ("You must provide a name server to enter an IP address."),
NameserverErrorCodes.INVALID_HOST: ("Enter a name server in the required format, like ns1.example.com"),
NameserverErrorCodes.DUPLICATE_HOST: (
"You already entered this name server address. Name server addresses must be unique."
),
NameserverErrorCodes.BAD_DATA: (
"Theres something wrong with the name server information you provided. "
"If you need help email us at help@get.gov."
),
}
def __init__(self, *args, code=None, nameserver=None, ip=None, **kwargs):
super().__init__(*args, **kwargs)
self.code = code
if self.code in self._error_mapping:
self.message = self._error_mapping.get(self.code)
if nameserver is not None and ip is not None:
self.message = self.message.format(str(nameserver))
elif nameserver is not None:
self.message = self.message.format(str(nameserver))
elif ip is not None:
self.message = self.message.format(str(ip))
def __str__(self):
return f"{self.message}"
class DsDataErrorCodes(IntEnum):
"""Used in the DsDataError class for
error mapping.
Overview of ds data error codes:
- 1 BAD_DATA bad data input in ds data
- 2 INVALID_DIGEST_SHA1 invalid digest for digest type SHA-1
- 3 INVALID_DIGEST_SHA256 invalid digest for digest type SHA-256
- 4 INVALID_DIGEST_CHARS invalid chars in digest
- 5 INVALID_KEYTAG_SIZE invalid key tag size > 65535
"""
BAD_DATA = 1
INVALID_DIGEST_SHA1 = 2
INVALID_DIGEST_SHA256 = 3
INVALID_DIGEST_CHARS = 4
INVALID_KEYTAG_SIZE = 5
class DsDataError(Exception):
"""
DsDataError class used to raise exceptions on
the ds data getter
"""
_error_mapping = {
DsDataErrorCodes.BAD_DATA: (
"Theres something wrong with the DS data you provided. If you need help email us at help@get.gov."
),
DsDataErrorCodes.INVALID_DIGEST_SHA1: ("SHA-1 digest must be exactly 40 characters."),
DsDataErrorCodes.INVALID_DIGEST_SHA256: ("SHA-256 digest must be exactly 64 characters."),
DsDataErrorCodes.INVALID_DIGEST_CHARS: ("Digest must contain only alphanumeric characters (0-9, a-f)."),
DsDataErrorCodes.INVALID_KEYTAG_SIZE: ("Key tag must be less than 65535."),
}
def __init__(self, *args, code=None, **kwargs):
super().__init__(*args, **kwargs)
self.code = code
if self.code in self._error_mapping:
self.message = self._error_mapping.get(self.code)
def __str__(self):
return f"{self.message}"
class SecurityEmailErrorCodes(IntEnum):
"""Used in the SecurityEmailError class for
error mapping.
Overview of security email error codes:
- 1 BAD_DATA bad data input in security email
"""
BAD_DATA = 1
class SecurityEmailError(Exception):
"""
SecurityEmailError class used to raise exceptions on
the security email form
"""
_error_mapping = {
SecurityEmailErrorCodes.BAD_DATA: ("Enter an email address in the required format, " "like name@example.com."),
}
def __init__(self, *args, code=None, **kwargs):
super().__init__(*args, **kwargs)
self.code = code
if self.code in self._error_mapping:
self.message = self._error_mapping.get(self.code)
def __str__(self):
return f"{self.message}"