Skip to content

Commit 88ae5eb

Browse files
committed
Make error messages more error friendly.
Avoid weird exception chaining to assertion errors.
1 parent 1b0b2de commit 88ae5eb

File tree

5 files changed

+28
-12
lines changed

5 files changed

+28
-12
lines changed

docs/project/changelog.rst

+11
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ They may change at any time.
5656
If you raise :exc:`~exceptions.ConnectionClosed` or a subclass — rather
5757
than catch them when websockets raises them — you must change your code.
5858

59+
.. note::
60+
61+
**Version 10.0 adds a ``msg`` parameter to** ``InvalidURI.__init__`` **.**
62+
63+
If you raise :exc:`~exceptions.InvalidURI` — rather than catch them when
64+
websockets raises them — you must change your code.
65+
66+
Also:
67+
5968
* Added compatibility with Python 3.10.
6069

6170
* Added :func:`~websockets.broadcast` to send a message to many clients.
@@ -150,6 +159,8 @@ They may change at any time.
150159
from websockets.client import connect
151160
from websockets.server import serve
152161

162+
Also:
163+
153164
* Added compatibility with Python 3.9.
154165

155166
* Added support for IRIs in addition to URIs.

src/websockets/exceptions.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,12 @@ class InvalidURI(WebSocketException):
374374
375375
"""
376376

377-
def __init__(self, uri: str) -> None:
377+
def __init__(self, uri: str, msg: str) -> None:
378378
self.uri = uri
379+
self.msg = msg
379380

380381
def __str__(self) -> str:
381-
return f"{self.uri} isn't a valid URI"
382+
return f"{self.uri} isn't a valid URI: {self.msg}"
382383

383384

384385
class PayloadTooBig(WebSocketException):

src/websockets/uri.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,12 @@ def parse_uri(uri: str) -> WebSocketURI:
5454
5555
"""
5656
parsed = urllib.parse.urlparse(uri)
57-
try:
58-
assert parsed.scheme in ["ws", "wss"]
59-
assert parsed.params == ""
60-
assert parsed.fragment == ""
61-
assert parsed.hostname is not None
62-
except AssertionError as exc:
63-
raise exceptions.InvalidURI(uri) from exc
57+
if parsed.scheme not in ["ws", "wss"]:
58+
raise exceptions.InvalidURI(uri, "scheme isn't ws or wss")
59+
if parsed.hostname is None:
60+
raise exceptions.InvalidURI(uri, "hostname isn't provided")
61+
if parsed.fragment != "":
62+
raise exceptions.InvalidURI(uri, "fragment identifier is meaningless")
6463

6564
secure = parsed.scheme == "wss"
6665
host = parsed.hostname
@@ -73,7 +72,7 @@ def parse_uri(uri: str) -> WebSocketURI:
7372
# urllib.parse.urlparse accepts URLs with a username but without a
7473
# password. This doesn't make sense for HTTP Basic Auth credentials.
7574
if parsed.password is None:
76-
raise exceptions.InvalidURI(uri)
75+
raise exceptions.InvalidURI(uri, "username provided without password")
7776
user_info = (parsed.username, parsed.password)
7877

7978
try:

tests/test_exceptions.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ def test_str(self):
142142
"WebSocket connection isn't established yet",
143143
),
144144
(
145-
InvalidURI("|"),
146-
"| isn't a valid URI",
145+
InvalidURI("|", "not at all!"),
146+
"| isn't a valid URI: not at all!",
147147
),
148148
(
149149
PayloadTooBig("payload length exceeds limit: 2 > 1 bytes"),

tests/test_uri.py

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
"ws://localhost/path?query",
1818
WebSocketURI(False, "localhost", 80, "/path?query", None),
1919
),
20+
(
21+
"ws://localhost/path;params",
22+
WebSocketURI(False, "localhost", 80, "/path;params", None),
23+
),
2024
(
2125
"WS://LOCALHOST/PATH?QUERY",
2226
WebSocketURI(False, "localhost", 80, "/PATH?QUERY", None),
@@ -39,6 +43,7 @@
3943
"https://localhost/",
4044
"ws://localhost/path#fragment",
4145
"ws://user@localhost/",
46+
"ws:///path",
4247
]
4348

4449

0 commit comments

Comments
 (0)