UnboundLocalError: local variable 'error' referenced before assignment

При выгрузке системы доната на Python Django начала появляться ошибка:

ошибка:

Internal Server Error: /pay
Traceback (most recent call last):
  File "C:\Users\Максимка\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\Максимка\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response     
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Максимка\Desktop\Projects\Python\Bots\FreezingBot\website\views.py", line 40, in pay
    invoce = q.new_invoice(payment=new_payment)
  File "C:\Users\Максимка\Desktop\Projects\Python\Bots\FreezingBot\website\qiwi_engine.py", line 77, in new_invoice
    sr = self.r(url=f'{self.__url}{payment.id}', params=options, r_type='PUT')
  File "C:\Users\Максимка\Desktop\Projects\Python\Bots\FreezingBot\website\qiwi_engine.py", line 56, in r
    'msg': error
UnboundLocalError: local variable 'error' referenced before assignment
[24/Jan/2023 21:02:23] "POST /pay HTTP/1.1" 500 77731```

views.py

import json

from django.shortcuts import render
from website.qiwi_engine import Qiwi
from website.models import Payments, Settings
from vkbot.settings import AUTH_TOKEN_ENDPOINTS
from django.http import HttpResponseRedirect, HttpResponse


def load_settings():
    settings = Settings.objects.all()
    if settings.count() > 0:
        return settings.last()
    else:
        return Settings.objects.create()


def index(request):
    settings = load_settings()

    data = {
        'notif_text': settings.notif_text
    }

    return render(request, "default/index.html", context=data)


def pay(request):
    if request.method == 'POST':
        first_name = request.POST.get('firstname')
        cost = request.POST.get('cost')

        if first_name is not None and cost is not None:
            if cost.isdigit():
                cost = int(cost)
                if cost >= 15 and cost <= 15000:
                    new_payment = Payments.objects.create(first_name=first_name, cost=cost)

                    q = Qiwi()
                    invoce = q.new_invoice(payment=new_payment)
                    if invoce['status']:
                        pay_url = invoce['data'].get('payUrl')
                        if pay_url is not None:
                            return HttpResponseRedirect(pay_url)
                        else:
                            return other_error(request=request, data={
                                'title': '500-06: Ошибка генерации ссылки на оплату',
                                'text': 'При создании ссылки на оплату пошло что-то не так!'
                            })
                    else:
                        return other_error(request=request, data={
                            'title': '500-05: Ошибка генерации ссылки на оплату',
                            'text': 'При создании ссылки на оплату пошло что-то не так!'
                        })
                else:
                    return other_error(request=request, data={
                        'title': '500-04: Ошибка формы',
                        'text': 'Сумма должна быть больше или равна 15 и меньше или равна 15 000!'
                    })
            else:
                return other_error(request=request, data={
                    'title': '500-02: Ошибка формы',
                    'text': 'Сумма в форме должна быть числом!'
                })
        else:
            return other_error(request=request, data={
                'title': '500-01: Ошибка формы',
                'text': 'Не правильно заполнены поля имени и суммы в форме!'
            })
    else:
        return other_error(request=request, data={
            'title': '500-03: Ошибка формы',
            'text': 'Адрес /pay принмиает только - POST запросы!'
        }, code=403)


def terms_of_use(request):
    settings = load_settings()

    data = {
        'title': 'Пользовательское соглашение',
        'text': settings.terms_of_use_text,
    }

    return render(request, "default/info_page.html", context=data)


def privacy_policy(request):
    settings = load_settings()

    data = {
        'title': 'Политика конфиденциальности',
        'text': settings.privacy_policy_text,
    }

    return render(request, "default/info_page.html", context=data)


def description_of_goods(request):
    settings = load_settings()

    data = {
        'title': 'Описание товаров',
        'text': settings.description_of_goods_text,
    }

    return render(request, "default/info_page.html", context=data)


def contacts(request):
    settings = load_settings()

    data = {
        'title': 'Контакты',
        'text': settings.contacts_text,
    }

    return render(request, "default/info_page.html", context=data)


def payments_list(request):
    if request.method == 'GET':
        token = request.GET.get('token')

        if token is not None and token == AUTH_TOKEN_ENDPOINTS:

            payments_data = Payments.objects.filter(complete=True, processed=False)

            p_list = [{
                'fn': p.first_name,
                'cost': p.cost
            } for p in payments_data]

            payments_data.update(processed=True)

            data = {
                'ststus': True,
                'result': p_list
            }
        else:
            data = {
                'status': False,
                'text': 'Авторизация не удалась!'
            }
    else:
        data = {
            'status': False,
            'text': 'Метод роута должен быть POST!'
        }

    return HttpResponse(json.dumps(data))


def other_error(request, data, code=500):
    load_settings()

    response = render(request, 'default/info_page.html', context=data)
    response.status_code = code

    return response


def handler403(request, *args, **argv):
    load_settings()

    data = {
        'title': '403: Ошибка доступа!',
        'text': 'Доступ к этому адресу запрещен!'
    }

    return other_error(request=request, data=data)


def handler404(request, *args, **argv):
    load_settings()

    data = {
        'title': '404: Страница не найдена!',
        'text': 'Такой страницы нет!'
    }

    return other_error(request=request, data=data)


def handler500(request, *args, **argv):
    load_settings()

    data = {
        'title': '500: Ошибка сервера!',
        'text': 'Что-то пошло не так!'
    }

    return other_error(request=request, data=data)```

urls.py:

from django.urls import path
from django.contrib import admin

from website import views

urlpatterns = [
    path('', views.index),
    path('pay', views.pay),

    path('terms_of_use/', views.terms_of_use),
    path('privacy_policy/', views.privacy_policy),
    path('description_of_goods/', views.description_of_goods),
    path('contacts/', views.contacts),
    path('payments_list/', views.payments_list),

    path('admin/', admin.site.urls),
]

handler403 = 'website.views.handler403'
handler404 = 'website.views.handler404'
handler500 = 'website.views.handler500'
```

В общем, промоделировать вашу ситуацию можно следующим образом:

error = '1'

try:
    x = 1 / 0
except Exception as error:
    print(error)
    error = error
    print(error)

print(error)

Вывод:

division by zero
division by zero
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-374efa19bb61> in <module>
      8     print(error)
      9 
---> 10 print(error)

NameError: name 'error' is not defined

В общем, после того, как вы перекрываете локальную переменную error переменной error, которая используется при ловле исключения, локальная переменная error перестаёт быть видимой. Интересный случай.

Вернуться на верх