text: Title: Websocket invalid upgrade exception handling b0rkage
  Body: ### Is there an existing issue for this?
  
  - [X] I have searched the existing issues
  
  ### Describe the bug
  
  A client apparently sent no Upgrade header to a websocket endpoint, leading to an error as it should. An ugly traceback is printed on terminal even though the error eventually gets handled correctly it would seem.
  
  It would appear that the websockets module attempts to attach its exception on `request._exception` field which Sanic's Request doesn't have a slot for. This could be hidden if Sanic later used `raise BadRequest(...) from None` rather than `raise SanicException(...)`, suppressing the chain and giving a non-500 error for what really is no server error. Not sure though if that would from this context ever reach the client anyway but at least it could avoid a traceback in server log.
  
  If anyone wants to investigate and make a PR, feel free to (I am currently busy and cannot do that unfortunately).
  
  ```python
  Traceback (most recent call last):
    File "/home/user/.local/lib/python3.10/site-packages/websockets/server.py", line 111, in accept
      ) = self.process_request(request)
    File "/home/user/.local/lib/python3.10/site-packages/websockets/server.py", line 218, in process_request
      raise InvalidUpgrade("Upgrade", ", ".join(upgrade) if upgrade else None)
  websockets.exceptions.InvalidUpgrade: missing Upgrade header
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
    File "/home/user/sanic/sanic/server/protocols/websocket_protocol.py", line 120, in websocket_handshake
      resp: "http11.Response" = ws_proto.accept(request)
    File "/home/user/.local/lib/python3.10/site-packages/websockets/server.py", line 122, in accept
      request._exception = exc
  AttributeError: 'Request' object has no attribute '_exception'
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
    File "handle_request", line 97, in handle_request
    File "/home/user/sanic/sanic/app.py", line 1047, in _websocket_handler
      ws = await protocol.websocket_handshake(request, subprotocols)
    File "/home/user/sanic/sanic/server/protocols/websocket_protocol.py", line 126, in websocket_handshake
      raise SanicException(msg, status_code=500)
  sanic.exceptions.SanicException: Failed to open a WebSocket connection.
  See server log for more information.
  ```
  
  
  ### Code snippet
  
  _No response_
  
  ### Expected Behavior
  
  400 Bad Request error reaching the client and being more silent on server side. Including the message of **missing Upgrade header** would be helpful for debugging (e.g. in case Nginx proxy config forgot to forward that header).
  
  ### How do you run Sanic?
  
  Sanic CLI
  
  ### Operating System
  
  Linux
  
  ### Sanic Version
  
  Almost 23.03.0 (a git version slightly before release)
  
  ### Additional context
  
  _No response_