Каналы Django – распространение исключений клиенту

Мне было интересно, как лучше всего передавать исключения клиенту, используяdjango-channels.
Мой клиент — приложение Swift для iOS, использующееURLSessionWebSocketTask.
Например, у меня есть 3 основных сценария, когда выдается исключение, и я хочу уведомить об этом клиента.

  1. Аутентификация с использованием специального промежуточного программного обеспечения.
      from api.jwt_handler import jwt_websocket_decode, get_device_id, get_auth_token
from inbox.exceptions import WebSocketErrors

class WebsocketAuthMiddleware:
    def __init__(self, app):
        self.app = app

    async def __call__(self, scope, receive, send):
        headers = scope["headers"]
        token = get_auth_token(headers)
        device_id = get_device_id(headers)

        if token is None or device_id is None:
            raise WebSocketErrors.invalid_bearer_token <--- Notify client

        user = await jwt_websocket_decode(token, device_id)

        if user is None:
            raise WebSocketErrors.invalid_bearer_token <--- Notify client

        scope['user'] = user

        return await self.app(scope, receive, send)

Я пробовал обертывать__call__в операторе try, но я не уверен, как передать ошибку на транспортный уровень http. Клиент получает1011 - There was a bad response from the server

  1. Отказ от соединения – рукопожатие.
      class ConversationConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.ws_conversation_id = self.scope["url_route"]["kwargs"]["conversation_id"]
        self.room_group_name = self.ws_conversation_id
        self.user = self.scope["user"]

        if user.can_participate_in_conversation(self.ws_conversation_id) is False:
            raise WebSocketErrors.not_authorized <--- Notify client

        await self.channel_layer.group_add(self.room_group_name, self.channel_name)

        await self.accept()

Здесь я хочу отклонить соединение, если пользователь не является частью данного идентификатора разговора, чтобы предотвратить злоупотребления.

  1. Внутрисессионная обработка данных – подключен веб-сокет.
          async def receive(self, bytes_data):
        message_json = json.loads(bytes_data)
        type = WebSocketType(message_json["type"])
        
        try:
            web_socket_item = self.get_websocket_item(type, message_json)
            user_id = self.scope["user"].id
            message_body = await web_socket_item.save_and_get_message_body(sender_id=user_id)
        except Exception as error:
            message_body = { 
                "type": WebSocketType.error.value,
                "error": {
                    "code": error.code,
                    "message": error.message
                }
            }

        # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name, 
            {"type": type.value, "message": message_body}
            )

Здесь я перехватил исключение и использовал открытое соединение для отправки сообщения с типом ошибки, но я не уверен, что это правильная практика.

Любое необработанное исключение, вызывающее отключение, и клиент получает то же самое.1011ошибка. Я хочу предотвратить отключение сокета в некоторых случаях (например, в 3) и дать клиенту возможность лучше обрабатывать ошибки.

0 ответов

Другие вопросы по тегам