question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Where assert statements are guarding against invalid ASGI messaging, use RuntimeError instead.

See original GitHub issue

Checklist

  • There are no similar issues or pull requests for this yet.
  • I discussed this idea on the community chat and feedback is positive.

Is your feature related to a problem? Please describe.

There are assert statements in the source code which raise a vague and hard to debug AssertionError. For example on this line.

If some kind of exception (for example something along the lines of: WebSocketMessageType) were raised it would make debugging a lot clearer. I spent a lot more time than I should have just working out where exactly this AssertionError was coming from and what the root cause was.

Describe the solution you would like.

This is by no means the right solution but at least it’s an idea of the kind of thing that might help:

class WebSocketMessageType(Exception):
    pass

class WebSocket(HTTPConnection):
    ...
    async def send(self, message: Message) -> None:
        """
        Send ASGI websocket messages, ensuring valid state transitions.
        """
        if self.application_state == WebSocketState.CONNECTING:
            message_type = message["type"]
            if message_type not in {"websocket.accept", "websocket.close"}:
                raise WebSocketMessageType("expected message_type to be websocket.accept or websocket.close")
            if message_type == "websocket.close":
                self.application_state = WebSocketState.DISCONNECTED
            else:
                self.application_state = WebSocketState.CONNECTED
            await self._send(message)
        elif self.application_state == WebSocketState.CONNECTED:
            message_type = message["type"]
            if message_type not in {"websocket.send", "websocket.close"}:
                raise WebSocketMessageType("expected message_type to be websocket.send or websocket.close")
            if message_type == "websocket.close":
                self.application_state = WebSocketState.DISCONNECTED
            await self._send(message)
        else:
            raise RuntimeError('Cannot call "send" once a close message has been sent.')

Describe alternatives you considered

No response

Additional context

The error I was seeing:

ERROR    root:a_file.py:31 {'message': 'Job processing failed', 'job': <Job coro=<<coroutine object a_class.a_method at 0x7f6d7a7c1ec0>>>, 'exception': AssertionError()}
NoneType: None

And this would be it with a raise statement: admittedly there is still no mention of starlette so a user would still have to diagnose that as the root cause.

ERROR    root:a_file.py:31 {'message': 'Job processing failed', 'job': <Job coro=<<coroutine object a_class.a_method at 0x7fb99c2ed940>>>, 'exception': WebSocketMessageType('expected message_type to be websocket.accept or websocket.close')}
NoneType: None

Also, I have no idea where that NoneType: None is coming from or what that means.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
agronholmcommented, Feb 3, 2022

Even in the case of such asserts, they ought to be accompanied with an appropriate error message (e.g. assert False, "foo should not be happening")

2reactions
tomchristiecommented, Feb 3, 2022

By all means, yup. Suggestion - keep it tightly scoped - just consider websockets.py in your pull request. (We con look at if there’s other cases as a follow-up)

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the use of "assert" in Python? - Stack Overflow
The assert statement exists in almost every programming language. It has two main uses: It helps detect problems early in your program, ...
Read more >
The dangers of assert in Python - Snyk
This article explores how to use asserts safely and what causes them to be unsafe. By the end of this article, you'll know...
Read more >
Python's assert: Debug and Test Your Code Like a Pro
In this tutorial, you'll learn how to use Python's assert statement to document, debug, and test code in development.
Read more >
pytest Documentation - Read the Docs
The first test passed and the second failed. You can easily see the intermediate values in the assertion to help you under-.
Read more >
How to write and report assertions in tests - Pytest
pytest allows you to use the standard Python assert for verifying expectations and values in Python tests. For example, you can write the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found