Воспроизвести ошибку в браузере, полученную на почте от Django

9 июля 2018 г. 4:26

Как правило, если возникает 500 ошибка вашего приложения на сервере, то посылается сгенерированный Django-отчёт об ошибке (трейсбек) электронным адресам, указанным в ADMINS в settings.py. Это может выглядеть примерно так:

Internal Server Error: /billing/online_reg_ip/

KeyError at /billing/online_reg_ip/
'birthday_day'

Request Method: POST
Request URL: https://site.ru/billing/online_reg_ip/
Django Version: 1.10.7
Python Executable: /usr/bin/uwsgi-core
Python Version: 2.7.9
Python Path: ['/path_to_project/src/', '.', '', ...]
Server time: Ср, 21 Мар 2018 08:40:50 +0800
Installed Applications: (u'django.contrib.contenttypes', ...)
Installed Middleware: (u'django.middleware.cache.UpdateCacheMiddleware', ...)

Traceback: 
File "/path_to_projet/env/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  42. response = get_response(request)
...
File "/path_to_projet/billing/forms.py" in clean
  100. del cleaned_data['birthday_day']

Exception Type: KeyError at /billing/online_reg_ip/
Exception Value: 'birthday_day'
Request information:
USER: AnonymousUser

POST:
comment = u'http://google01**.com/'
birthday_day = u'1980-12-12'
first_name = u'Hoz GT'
csrfmiddlewaretoken = 'f6p***'
...

COOKIES:
csrftoken = 'f6p***'

Это реальная ошибка моего клиентского проекта, которая пришла мне на почту (для сокращения я убрал ненужные части этого отчёта). По POST-данным видно, что форму заполнял робот, и радует: хоть не у реального клиента она возникла :)

Я быстро исправил ошибку, добавив проверку существования ключа в словаре, но как теперь протестировать? Забить вручную все POST-данные в форме? Это долго и тем более нужно будет тогда отключить проверку js, закомментировав строки в шаблоне. Поэтому лучше всё это дело автоматизировать.

В простейшем случае вы можете написать management-команду, которая отправит POST-данные на ваш локальный сервер по указанному пути и, получив данные, откроет в браузере страницу, в которой вы можете наглядно увидеть, что открывается именно ожидаемая страница:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.conf import settings
from django.core.management.base import BaseCommand

import requests
from os.path import join
import webbrowser


class Command(BaseCommand):
    def handle(self, *args, **options):

        url = 'http://localhost:8001/billing/online_reg_ip/'

        data = dict(comment=u'http://google01**.com/',
                    birthday_day=u'1980-12-12',
                    first_name=u'HolaBromz GT',
                    csrfmiddlewaretoken=u'f6p***',
                    ...)

        client = requests.session()
        client.get(url)

        data['csrfmiddlewaretoken'] = client.cookies['csrftoken']
        r = client.post(url, data)

        path = join(settings.MEDIA_ROOT, 'test.html')
        with open(path, 'w') as f:
            f.write(r.text.encode('utf-8'))

        webbrowser.open('file://{}'.format(path))

С помощью этой простой команды вы можете проверять нужный url с POST-данными.

Обратите внимание, что мы должны получить свой csrftoken, а не использовать тот, который использовал робот. В противном случае на локальной машине вы получите ответ сервера 403 Forbidden. Чтобы избежать эту ошибку, нам нужно открыть сессию requests.session() и получить любой url, чтобы наш client сохранил данные cookie. Когда данные получены, остаётся заменить значение ключа csrfmiddlewaretoken в отправляемых данных.

Для удобства полученные данные сервера я сохраняю в файле test.html в папку media (эта папка соответствует значению переменной MEDIA в settings.py), чтобы проверяемая страница test.html случайно не попала в репозиторий. В .hgignore у меня настроено так, что только placeholder в папке media попадает в репозиторий:

...
syntax: regexp
media/(?!placeholder)
...

Полученный файл автоматом открываем в браузере командой webbrowser.open().

И наконец, чтобы на странице отображалась статика, я использую следующие настройки:

MEDIA_ROOT = os.path.join(ROOT_DIR, 'media')
MEDIA_URL = '/media/' if not DEBUG else ''

STATIC_ROOT = os.path.join(ROOT_DIR, 'collect_static')
STATIC_URL = '/static/' if not DEBUG else '../collect_static/'

Для меня пока выше написанного кода достаточно для тестирования. Возможно, есть хорошие инструменты, которые ещё удобнее. Подозреваю, что есть приложение, позволяющее в админке отображать ошибки и удобно тестировать с разными POST-данными. Если знаете, поделитесь ;)

Оцените статью

0 из 5 (всего 0 оценок)

captcha
Отмеченные звёздочкой поля ( * ) являются обязательными для заполнения.

Спасибо за ваш отзыв!

После нажатия кнопки "Отправить" ваше сообщение будет доставлено мне на почту.

Автор статьи

Артём Мальцев

Веб-разработчик, владеющий знаниями языка программирования Python, фреймворка Django, системы управления содержимым сайта Django CMS, платформы для создания интернет-магазина Django Shop и многих различных приложений, использующих эти технологии.

Права на использование материала, расположенного на этой странице https://vivazzi.pro/ru/it/error-reproducing/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор статьи: Артём Мальцев
Ссылка на статью: <a href="https://vivazzi.pro/ru/it/error-reproducing/">https://vivazzi.pro/ru/it/error-reproducing/</a>

Больше: Правила использования сайта

Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.

Книга предназначается для широкого круга читателей и, по мнению автора, будет полезна специалистам отдела закупок и логистики, категорийным и финансовым менеджерам, менеджерам по продажам, аналитикам, руководителям и директорам, в компетенции которых принятие решений по управлению ассортиментом.

Комментарии: 0

Вы можете оставить комментарий как незарегистрированный пользователь.

Но зарегистрировавшись, вы сможете:

  • получать оповещения об ответах
  • просматривать свои комментарии
  • иметь возможность использовать все функции разработанных сервисов

Для комментирования от своего имени войдите или зарегистрируйтесь на сайте Vuspace

Отправить

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте

Выберите валюту для отображения денежных единиц