1"""Exceptions module for rfc3986."""
2
3import typing as t
4
5from . import compat
6from . import uri
7
8
9class RFC3986Exception(Exception):
10 """Base class for all rfc3986 exception classes."""
11
12 pass
13
14
15class InvalidAuthority(RFC3986Exception):
16 """Exception when the authority string is invalid."""
17
18 def __init__(self, authority: t.Union[str, bytes]) -> None:
19 """Initialize the exception with the invalid authority."""
20 super().__init__(
21 f"The authority ({compat.to_str(authority)}) is not valid."
22 )
23
24
25class InvalidPort(RFC3986Exception):
26 """Exception when the port is invalid."""
27
28 def __init__(self, port: str) -> None:
29 """Initialize the exception with the invalid port."""
30 super().__init__(f'The port ("{port}") is not valid.')
31
32
33class ResolutionError(RFC3986Exception):
34 """Exception to indicate a failure to resolve a URI."""
35
36 def __init__(self, uri: "uri.URIReference") -> None:
37 """Initialize the error with the failed URI."""
38 super().__init__(
39 "{} does not meet the requirements for resolution.".format(
40 uri.unsplit()
41 )
42 )
43
44
45class ValidationError(RFC3986Exception):
46 """Exception raised during Validation of a URI."""
47
48 pass
49
50
51class MissingComponentError(ValidationError):
52 """Exception raised when a required component is missing."""
53
54 def __init__(self, uri: "uri.URIReference", *component_names: str) -> None:
55 """Initialize the error with the missing component name."""
56 verb = "was"
57 if len(component_names) > 1:
58 verb = "were"
59
60 self.uri = uri
61 self.components = sorted(component_names)
62 components = ", ".join(self.components)
63 super().__init__(
64 f"{components} {verb} required but missing",
65 uri,
66 self.components,
67 )
68
69
70class UnpermittedComponentError(ValidationError):
71 """Exception raised when a component has an unpermitted value."""
72
73 def __init__(
74 self,
75 component_name: str,
76 component_value: t.Any,
77 allowed_values: t.Collection[t.Any],
78 ) -> None:
79 """Initialize the error with the unpermitted component."""
80 super().__init__(
81 "{} was required to be one of {!r} but was {!r}".format(
82 component_name,
83 list(sorted(allowed_values)),
84 component_value,
85 ),
86 component_name,
87 component_value,
88 allowed_values,
89 )
90 self.component_name = component_name
91 self.component_value = component_value
92 self.allowed_values = allowed_values
93
94
95class PasswordForbidden(ValidationError):
96 """Exception raised when a URL has a password in the userinfo section."""
97
98 def __init__(self, uri: t.Union[str, "uri.URIReference"]) -> None:
99 """Initialize the error with the URI that failed validation."""
100 unsplit = getattr(uri, "unsplit", lambda: uri)
101 super().__init__(
102 '"{}" contained a password when validation forbade it'.format(
103 unsplit()
104 )
105 )
106 self.uri = uri
107
108
109class InvalidComponentsError(ValidationError):
110 """Exception raised when one or more components are invalid."""
111
112 def __init__(self, uri: "uri.URIReference", *component_names: str) -> None:
113 """Initialize the error with the invalid component name(s)."""
114 verb = "was"
115 if len(component_names) > 1:
116 verb = "were"
117
118 self.uri = uri
119 self.components = sorted(component_names)
120 components = ", ".join(self.components)
121 super().__init__(
122 f"{components} {verb} found to be invalid",
123 uri,
124 self.components,
125 )
126
127
128class MissingDependencyError(RFC3986Exception):
129 """Exception raised when an IRI is encoded without the 'idna' module."""