Как увидеть исключения, возникшие у потребителя канала - PullRequest
0 голосов
/ 31 января 2019

Я начинаю использовать django-channels и нахожу это фантастическим.Однако отладка потребителей является болезненной, потому что когда некоторые исключения вызываются изнутри потребителя, на терминал ничего не печатается, веб-розетка просто отключается.

Вид не показанного исключения не очевиден для идентификации.Систематически это относится к AssertionError, а также к некоторым другим, например коду ниже:

class MexicoProgressConsumer(ProgressConsumer):
    def init(self, SSDBConfig, Sub_application):
        subappli = models.Sub_application.objects.get(pk=Sub_application)
        ...

Вызов этого метода с неправильным числом аргументов ничего не выводит на консоль и не отключает веб-сокет,Представьте себе, если get в последней строке не удалось.

Есть ли способ увидеть эти исключения как любые другие?

1 Ответ

0 голосов
/ 02 февраля 2019

Я нашел решение своей проблемы.Сначала я определяю декоратор:

import traceback
def catch_exception(f):
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except StopConsumer:
            raise
        except Exception as e:
            print(traceback.format_exc().strip('\n'), '<--- from consumer')
            raise
    return wrapper

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

import inspect
class BaseConsumer(JsonWebsocketConsumer):
    def __getattribute__(self, name):
        value = object.__getattribute__(self, name)
        if inspect.ismethod(value):
            return catch_exception(value)
        return value

Но сохраняются 2 проблемы:

  • Обычно показанные исключения появляются дважды
  • Другие исключения повторяются 3 или 4 раза!(как будто срабатывает каждый уровень иерархии классов)

Пример первого случая (KeyError):

Traceback (most recent call last):
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 31, in wrapper
    result = f(owner, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 110, in refresh
    data = super().refresh.__wrapped__(self)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 73, in refresh
    pvalue = round(data['toto'] * 100, 1)
KeyError: 'toto' <--- from consumer
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/alain/ADN/simutool/dbsimu/utils.py", line 193, in repeat
    self.repeat_func()
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 31, in wrapper
    result = f(owner, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 110, in refresh
    data = super().refresh.__wrapped__(self)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 73, in refresh
    pvalue = round(data['toto'] * 100, 1)
KeyError: 'toto'

Пример второго случая (переменная с ошибкой):

WebSocket CONNECT /ws/dbsimu/Simuflow_progress/ [127.0.0.1:55866]
Traceback (most recent call last):
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 57, in receive_json
    return getattr(self, icommand)(**data)
NameError: name 'icommand' is not defined <--- from consumer
Traceback (most recent call last):
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/.local/lib/python3.6/site-packages/channels/generic/websocket.py", line 125, in receive
    self.receive_json(self.decode_json(text_data), **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 57, in receive_json
    return getattr(self, icommand)(**data)
NameError: name 'icommand' is not defined <--- from consumer
Traceback (most recent call last):
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/.local/lib/python3.6/site-packages/channels/generic/websocket.py", line 60, in websocket_receive
    self.receive(text_data=message["text"])
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/.local/lib/python3.6/site-packages/channels/generic/websocket.py", line 125, in receive
    self.receive_json(self.decode_json(text_data), **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 19, in wrapper
    return f(*args, **kwargs)
  File "/home/alain/ADN/simutool/dbsimu/consumers.py", line 57, in receive_json
    return getattr(self, icommand)(**data)
NameError: name 'icommand' is not defined <--- from consumer

Если у кого-нибудь есть идея, чтобы исправить это, пожалуйста, сообщите.

...