Search code examples
djangotracebackdjango-debug-toolbar

Django Debug=False returns error traceback


I support Django 4.0 project and notice that even though DEBUG=False, all errors return with tracebacks. I've commented all extras in settings.py, but still receive the traceback. All variebles are deffinately loading (DEBUG) and it happens both localy and on server. we don't need templates to return, just return json, so simply return the basic functionality. Please, give ideas where to look at?

# from pathlib import Path
import os
from datetime import timedelta
from django.utils.translation import gettext_lazy as _  # for translation
from dotenv import load_dotenv
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
from django.utils import timezone
from logging.handlers import TimedRotatingFileHandler


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROGECT_DIR = os.path.dirname(os.path.dirname((BASE_DIR)))
load_dotenv(os.path.join(PROGECT_DIR,
                         'infra',
                         '.env'), verbose=True)

ENVIRONMENT = os.getenv('ENVIRONMENT')
DEVELOPER = os.getenv('DEVELOPER')

# LOG_DIRECTORY = os.path.join(BASE_DIR, 'logging')
# if not os.path.exists(LOG_DIRECTORY):
#     os.makedirs(LOG_DIRECTORY)

# LOGGING = {
#     "version": 1,
#     "disable_existing_loggers": False,
#     "formatters": {
#         "verbose": {
#             "format": "{levelname} {asctime} {pathname} {funcName} {process:d} {thread:d} {message}",
#             "style": "{",
#         },
#     },
#     "handlers": {
#         "console": {
#             "level": os.getenv('CONSOLE_LOG_LEVEL', 'DEBUG'),
#             "class": "logging.StreamHandler",
#             "formatter": "verbose",
#         },
#         "file": {
#             'level': os.getenv('FILE_LOG_LEVEL', 'DEBUG'),
#             'class': 'logging.handlers.TimedRotatingFileHandler',
#             'filename': os.path.join(LOG_DIRECTORY, 'yume.log'),
#             'formatter': 'verbose',
#             'encoding': 'utf-8',
#             # 'mode': 'a',
#             'when': 'midnight',
#             # 'interval': 1,
#             'backupCount': 10
#         },
#         "mail": {
#             'level': 'ERROR',
#             'class': 'logging.handlers.SMTPHandler',
#             'mailhost': (os.getenv('EMAIL_HOST'), os.getenv('EMAIL_PORT')),
#             'fromaddr': os.getenv('EMAIL_HOST_USER'),
#             'toaddrs': ['[email protected]'],
#             'subject': 'Django Error Log',
#             'credentials': (os.getenv('EMAIL_HOST_USER'),
#                             os.getenv('EMAIL_HOST_PASSWORD')),
#             'secure': (),
#         },
#     },
#     "loggers": {
#         "api": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('API_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "catalog": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('CATALOG_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "delivery_contacts": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('DELIVERY_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "promos": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('PROMOS_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "shop": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('SHOP_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "tm_bot": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('TM_BOT_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "users": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('USERS_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "cron": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('CRON_LOG_LEVEL'),
#             "propagate": True,
#         },
#         "web_shop_with_bots": {
#             "handlers": [*(["console"] if os.getenv(
#                             'ENABLE_CONSOLE_LOGGING',
#                             'True') == 'True' else []),
#                          *(["file"] if os.getenv(
#                              'ENABLE_FILE_LOGGING',
#                              'True') == 'True' else []),
#                          *(["mail"] if os.getenv(
#                              'ENABLE_MAIL_LOGGING',
#                              'True') == 'True' else [])],
#             "level": os.getenv('WSWB_LOG_LEVEL'),
#             "propagate": True,
#         },
#     },
# }

SECRET_KEY = os.getenv('SECRET_KEY')


DOCKER_COMPOSE_NAME = os.getenv('DOCKER_COMPOSE_NAME')

DEBUG = os.getenv('DEBUG')
TEST_SERVER = os.getenv('TEST_SERVER')
SERVER = os.getenv('SERVER')

GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')

default_allowed_hosts = [
    'localhost',
    '127.0.0.1',
    '[::1]',
]

allowed_hosts = default_allowed_hosts.copy()
# Insert the TEST_SERVER and SERVER into the list if available
if TEST_SERVER or SERVER:
    if TEST_SERVER:
        allowed_hosts.append(str(TEST_SERVER))
    elif SERVER:
        allowed_hosts.append(str(SERVER))


if ENVIRONMENT in ['development', 'test_server']:
    allowed_hosts.append('testserver')
ALLOWED_HOSTS = allowed_hosts


default_installed_apps = [
    'catalog.apps.CatalogConfig',
    'shop.apps.ShopConfig',
    'users.apps.UsersConfig',
    'tm_bot.apps.TmBotConfig',
    'promos.apps.PromosConfig',
    'delivery_contacts.apps.DeliveryContactsConfig',
    'settings.apps.SettingsConfig',
    'audit.apps.AuditConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django_extensions',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework_simplejwt',
    'rest_framework_simplejwt.token_blacklist',
    'djoser',
    'corsheaders',
    'drf_yasg',
    'rest_framework.authtoken',
    'django_filters',
    'parler',   # language
    'django.contrib.gis',
    'rangefilter',
    'django_summernote',
    'django_admin_inline_paginator',
    'debug_toolbar',
]
installed_apps = default_installed_apps.copy()
# Insert the TEST_SERVER and SERVER into the list if available
if SERVER:
    installed_apps.remove('debug_toolbar',)

INSTALLED_APPS = installed_apps


MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    #'web_shop_with_bots.middlewares.AdminRULocaleMiddleware',
    # return admin page in RU
    #'web_shop_with_bots.middlewares.APIENLocaleMiddleware',
    # set EN language as default for API server replies
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',

    #'web_shop_with_bots.middlewares.AuditMiddleware',
    # auditlog for users activities
    #'web_shop_with_bots.middlewares.APILoggingMiddleware',
    # logging all requests to API

    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    #'debug_toolbar.middleware.DebugToolbarMiddleware',

]

ROOT_URLCONF = 'web_shop_with_bots.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates/')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'web_shop_with_bots.wsgi.application'

POSTGRES_DB = os.environ.get('POSTGRES_DB')
POSTGRES_USER = os.environ.get('POSTGRES_USER')
POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD')

DATABASES = {
    'default': {
        'ENGINE': os.environ.get('DB_ENGINE'),
        'NAME': POSTGRES_DB,
        'USER': POSTGRES_USER,
        'PASSWORD': POSTGRES_PASSWORD,
        'HOST': os.environ.get('DB_HOST'),
        'PORT': os.environ.get('DB_PORT'),
    }
}

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'users.validators.AlphanumericPasswordValidator',
    },
    {
        'NAME': 'users.validators.MaximumLengthValidator',
    },
]


REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],

    'DATE_FORMAT': "%d.%m.%Y",

    'DATE_INPUT_FORMATS': [
        "%d.%m.%Y",
    ],

    'DATETIME_FORMAT': '%d.%m.%Y %H:%M',

    'DATETIME_INPUT_FORMATS': [
        '%d.%m.%Y %H:%M',
    ],
    #'EXCEPTION_HANDLER': 'api.utils.utils.custom_exception_handler',

    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.UserRateThrottle',
        'rest_framework.throttling.AnonRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'user': '10000/day', #  Лимит для UserRateThrottle
        'anon': '1000/day',  #  Лимит для AnonRateThrottle
    }
}

access_token_lifetime = os.getenv('ACCESS_TOKEN_LIFETIME')
refresh_token_lifetime = os.getenv('REFRESH_TOKEN_LIFETIME')

if access_token_lifetime is not None:
    ACCESS_TOKEN_LIFETIME = timedelta(seconds=int(access_token_lifetime))
else:
    ACCESS_TOKEN_LIFETIME = timedelta(seconds=480)

if refresh_token_lifetime is not None:
    REFRESH_TOKEN_LIFETIME = timedelta(seconds=int(refresh_token_lifetime))
else:
    REFRESH_TOKEN_LIFETIME = timedelta(seconds=7776000)

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': ACCESS_TOKEN_LIFETIME,
    'REFRESH_TOKEN_LIFETIME': REFRESH_TOKEN_LIFETIME,
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'AUTH_HEADER_TYPES': ('Bearer',),

    'BLACKLIST_AFTER_ROTATION': True,
}

TOKEN_MODEL = None
BLACKLIST_MODEL = 'yourapp.BlacklistedToken'

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = os.getenv('EMAIL_HOST')
EMAIL_USE_TLS = os.getenv('EMAIL_USE_TLS')
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
EMAIL_PORT = os.getenv('EMAIL_PORT')

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
EMAIL_ADMIN = EMAIL_HOST_USER

DOMAIN = os.getenv('DOMAIN')
PROTOCOL = os.getenv('PROTOCOL')
SITE_NAME = os.getenv('SITE_NAME')

DJOSER = {
    'LOGIN_FIELD': 'email',
    'SEND_ACTIVATION_EMAIL': True,
    'SEND_CONFIRMATION_EMAIL': True,
    'ACTIVATION_URL': 'activation/{uid}/{token}',

    'USERNAME_CHANGED_EMAIL_CONFIRMATION': True,

    'PASSWORD_RESET_CONFIRM_URL': 'reset_password_confirm/{uid}/{token}',
    'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': True,
    'PASSWORD_CHANGED_EMAIL_CONFIRMATION': True,
    'LOGOUT_ON_PASSWORD_CHANGE': True,

    'SERIALIZERS': {
        'current_user': 'api.serializers.MyUserSerializer',
        'user_create': 'api.serializers.MyUserCreateSerializer'
    },
    'EMAIL': {
        'activation': 'api.utils.email.MyActivationEmail',
        'confirmation': 'api.utils.email.MyConfirmationEmail',
        'password_reset': 'api.utils.email.MyPasswordResetEmail',
        'password_changed_confirmation': 'api.utils.email.MyPasswordChangedConfirmationEmail',
        'username_changed_confirmation': 'api.utils.email.MyUsernameChangedConfirmationEmail',
    },
    'PERMISSIONS': {
        # 'user_delete': ['api.permissions.DenyAllPermission'],
        'username_reset': ['api.permissions.DenyAllPermission'],
        'username_reset_confirm': ['api.permissions.DenyAllPermission'],
    },
}

# -------------------------------- DATETIME + OTHER ------------------------------------------

TIME_ZONE = 'Europe/Belgrade'

USE_TZ = True

DATE_FORMAT = "d.m.Y"
DATE_INPUT_FORMATS = ["%d.%m.%Y",]

DATETIME_FORMAT = "d.m.Y H:i"
DATETIME_INPUT_FORMATS = ["%d.%m.%Y %H:%i",]


DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

AUTH_USER_MODEL = 'users.WEBAccount'


STATIC_URL = 'static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'my_static/'),]
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

# -------------------------------- CORS ------------------------------------------

CORS_ORIGIN_ALLOW_ALL = True

default_cors_allowed_origins = [
    f"{PROTOCOL}://localhost:3000",
    f"{PROTOCOL}://127.0.0.1",
]

cors_allowed_origins = default_cors_allowed_origins.copy()
if TEST_SERVER or SERVER:
    if TEST_SERVER:
        cors_allowed_origins.append(f"{PROTOCOL}://{TEST_SERVER}")
    elif SERVER:
        cors_allowed_origins.append(f"{PROTOCOL}://{SERVER}")
CORS_ALLOWED_ORIGINS = cors_allowed_origins

CORS_ALLOW_CREDENTIALS = True

# -------------------------------- CSRF --------------------------------------------

SESSION_COOKIE_AGE = int(os.getenv('SESSION_COOKIE_AGE'))

if ENVIRONMENT != 'development':
    CSRF_COOKIE_SECURE = True

CSRF_COOKIE_HTTPONLY = True
CSRF_USE_SESSIONS = True

default_csrf_trusted_origins = [
    f"{PROTOCOL}://localhost:3000",
    f"{PROTOCOL}://127.0.0.1",
]

csrf_trusted_origins = default_csrf_trusted_origins.copy()

# Insert the TEST_SERVER and SERVER into the list if available
if TEST_SERVER or SERVER:
    if TEST_SERVER:
        csrf_trusted_origins.append(str(f"{PROTOCOL}://{TEST_SERVER}"))
    elif SERVER:
        csrf_trusted_origins.append(str(f"{PROTOCOL}://{SERVER}"))
CSRF_TRUSTED_ORIGINS = csrf_trusted_origins

REST_USE_JWT = True

# -------------------------------- DEBUG TOOL BAR --------------------------------------------

default_internal_ips = [
    '127.0.0.1',
]

internal_ips_origins = default_internal_ips.copy()

# Insert the TEST_SERVER and SERVER into the list if available
if TEST_SERVER:
    internal_ips_origins.append(str(TEST_SERVER))

INTERNAL_IPS = internal_ips_origins


# -------------------------------- SENTRY MISTAKES INFORMATION----------------------------

if ENVIRONMENT in ['test_server', 'production']:
    sentry_sdk.init(
        dsn=os.getenv('SENTRY_DSN'),
        integrations=[DjangoIntegration()],
    )


I commented all extras in settings.py to come back to the basics, but invain, traceback still returns. I also tried to add error handlers in the main project urls.py and return JsonResponse, but they aren't triggered.


Solution

  • Even if it is False, that will be seen as true. Because the truthiness of a non-empty string is True, even if that string contains 'False'.

    I would check with True instead, so:

    DEBUG = os.getenv('DEBUG') == 'True'

    That way, you explicitly need to set DEBUG=True as environment variable. true, 1, nothing set, etc. will all asume debug is False.