# Source code for headerparser.errors

    from typing import Any

    class Error(Exception):
        """Superclass for all custom exceptions raised by the package"""

        pass

    class ParserError(Error, ValueError):
        """Superclass for all custom exceptions related to errors in parsing"""

        pass

    class MissingFieldError(ParserError):
        """
        Raised when a header field marked as required is not present in the input
        """

        def __init__(self, name: str) -> None:
            #: The name of the missing header field
            self.name: str = name

        def __str__(self) -> str:
            return f"Required header field {self.name!r} is not present"

    class UnknownFieldError(ParserError):
        """
        Raised when an unknown header field is encountered and additional header
        fields are not enabled
        """

        def __init__(self, name: str) -> None:
            #: The name of the unknown header field
            self.name: str = name

        def __str__(self) -> str:
            return f"Unknown header field {self.name!r}"

    class DuplicateFieldError(ParserError):
        """
        Raised when a header field not marked as multiple occurs two or more times
        in the input
        """

        def __init__(self, name: str) -> None:
            #: The name of the duplicated header field
            self.name: str = name

        def __str__(self) -> str:
            return f"Header field {self.name!r} occurs more than once"

    class FieldTypeError(ParserError):
        """Raised when a ``type`` callable raises an exception"""

        def __init__(self, name: str, value: str, exc_value: BaseException) -> None:
            #: The name of the header field for which the ``type`` callable was
            #: called
            self.name: str = name
            #: The value on which the ``type`` callable was called
            self.value: str = value
            #: The exception raised by the ``type`` callable
            self.exc_value: BaseException = exc_value

        def __str__(self) -> str:
            return (
                f"Error while parsing {self.name!r}: {self.value!r}:"
                f" {self.exc_value.__class__.__name__}: {self.exc_value}"
            )

    class InvalidChoiceError(ParserError):
        """
        Raised when a header field is given a value that is not one of its allowed
        choices
        """

        def __init__(self, name: str, value: Any) -> None:
            #: The name of the header field
            self.name: str = name
            #: The invalid value
            self.value: Any = value

        def __str__(self) -> str:
            return f"{self.value!r} is not a valid choice for {self.name!r}"

    class MissingBodyError(ParserError):
        """Raised when ``body=True`` but there is no message body in the input"""

        def __str__(self) -> str:
            return "Message body is required but missing"

    class BodyNotAllowedError(ParserError):
        """Raised when ``body=False`` and the parser encounters a message body"""

        def __str__(self) -> str:
            return "Message body is present but not allowed"

    class ScannerError(Error, ValueError):
        """Superclass for all custom exceptions related to errors in scanning"""

        pass

    class MalformedHeaderError(ScannerError):
        """
        Raised when the scanner encounters an invalid header line, i.e., a line
        without either a colon or leading whitespace
        """

        def __init__(self, line: str) -> None:
            #: The invalid header line
            self.line: str = line

        def __str__(self) -> str:
            return f"Invalid header line encountered: {self.line!r}"

    class UnexpectedFoldingError(ScannerError):
        """
        Raised when the scanner encounters a folded (indented) line that is not
        preceded by a valid header line
        """

        def __init__(self, line: str) -> None:
            #: The line containing the unexpected folding (indentation)
            self.line: str = line

        def __str__(self) -> str:
            return f"Indented line without preceding header line encountered: {self.line!r}"

    class ScannerEOFError(Error):
        """
        Raised when a `Scanner` method is called after all input has been exhausted
        """

        def __str__(self) -> str:
            return "Scanner has reached end of input"