5

I am getting a funny 500 error when I switch to Debug=False in my Heroku app when I deploy. I have set Debug=True when I deploy just to try it out and it works perfectly - so the issue is only when Debug is set to False.

I'm not sure where to start here. Some searching has led me to believe it's whitenoise causing the issue but it's not clear. The command:

Output from heroku logs --source app

2018-09-13T12:29:53.137785+00:00 app[web.1]: 10.45.76.149 - - [13/Sep/2018:12:29:53 +0000] "GET / HTTP/1.1" 500 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
2018-09-13T12:29:53.279702+00:00 app[web.1]: 10.81.224.221 - - [13/Sep/2018:12:29:53 +0000] "GET /favicon.ico HTTP/1.1" 404 85 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
2018-09-13T12:29:53.792280+00:00 app[web.1]: 10.45.76.149 - - [13/Sep/2018:12:29:53 +0000] "GET /favicon.ico HTTP/1.1" 404 85 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"

I have tried fixing as per this solution but to no avail;

See below for my settings:

import os
import posixpath
from os import environ

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))



# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'A SECRET'

DEBUG = True

ALLOWED_HOSTS = ['*']




SITE_TITLE = "Penguiness"
SITE_TAGLINE = "Amazing records for amazing species"

# Application definition

INSTALLED_APPS = [
    'app',
    # Add your apps here to enable them
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'compressor',
    'gunicorn'
]

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
]

ROOT_URLCONF = 'Penguinness.urls'


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/


# STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

STATIC_URL = '/static/'

STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['app/static']))

PROJECT_APP_PATH = os.path.dirname(os.path.abspath(__file__))
PROJECT_APP = os.path.basename(PROJECT_APP_PATH)
PROJECT_ROOT = BASE_DIR = os.path.dirname(PROJECT_APP_PATH)


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(PROJECT_ROOT, "app/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',
                'app.context_processors.global_settings',                
            ],
        },
    },
]

WSGI_APPLICATION = 'Penguinness.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases

# DATABASES = {
#     'default': {
#         DATABASE STUFF
#     }
# }





SECURE_PROXY_SSL_HEADER = (
    "HTTP_X_FORWARDED_PROTO", 
    "https"
    )





# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

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',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_PASSWORD = PASSWORD #my gmail password
EMAIL_HOST_USER = EMAIL  #my gmail username
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER


import dj_database_url
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' +
                       'pathname=%(pathname)s lineno=%(lineno)s ' +
                       'funcname=%(funcName)s %(message)s'),
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        }
    },
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'testlogger': {
            'handlers': ['console'],
            'level': 'INFO',
        }
    }
}
GrantRWHumphries
  • 612
  • 7
  • 22
  • IMO you're going to have a hard time debugging without seeing the logs of what's actually happening. Try adding `--source app` to your `heroku logs` command and see if that shows what's causing it. If so, please paste the full stack trace. – wholevinski Sep 13 '18 at 10:58
  • `heroku logs --source --app APPNAME` (replaced with the name of my app) is just throwing me an 'unexpected argument' error. `heroku logs --source APPNAME` is telling me to use the -a or --app flag. – GrantRWHumphries Sep 13 '18 at 11:20
  • I'm pretty sure it's just `--source app`, not `--source --app APPNAME`. That's what their docs imply: https://devcenter.heroku.com/articles/logging – wholevinski Sep 13 '18 at 11:22
  • Also looks like you don't have a logging config in your `settings.py`. Try adding something along these lines: https://stackoverflow.com/a/20983546/769971 – wholevinski Sep 13 '18 at 11:33
  • just commit out this line ```STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' ``` – Hozayfa El Rifai Sep 13 '18 at 11:43
  • @wholevinski - I tried that as well and get a "missing flag" error `heroku logs --source app` then I get: `Error: Missing required flag: › -a, --app APP app to run command against` – GrantRWHumphries Sep 13 '18 at 12:27
  • @houzayfarifai - tried that and to no avail. – GrantRWHumphries Sep 13 '18 at 12:35
  • @wholevinski thanks for that - I added logging and now the heroku logs --source app works. However (you can see the output in the edits) - it gave me no new information – GrantRWHumphries Sep 13 '18 at 12:35

7 Answers7

18

Okay - having battled for a bit I've found a solution to both issues I was having.

Issue 1: Unable to view heroku logs --source app:

I had to first add LOGGING to the settings.py file:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' +
                       'pathname=%(pathname)s lineno=%(lineno)s ' +
                       'funcname=%(funcName)s %(message)s'),
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        }
    },
    'handlers': {
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'testlogger': {
            'handlers': ['console'],
            'level': 'INFO',
        }
    }
}

More importantly was to get the relevant errors to propagate up through the Heroku logs. To do this, in settings.py I wrote the line:

DEBUG_PROPAGATE_EXCEPTIONS = True

This gave me an error associated with my static files. More specifically, it was giving me this error:

ValueError: Missing staticfiles manifest entry for 'images/favicon.png'

Issue 2: the 500 error

After determining that there was an error processing static images, I searched and someone suggested running:

python manage.py collectstatic

I did this, but was still finding the error. The next thing was to ensure that Whitenoise was commented out:

#STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

However, this was resulting in the error:

2018-09-13T13:13:49.905187+00:00 app[web.1]: "When using Django Compressor together with staticfiles, "
2018-09-13T13:13:49.905190+00:00 app[web.1]: ImproperlyConfigured: When using Django Compressor together with staticfiles, please add 'compressor.finders.CompressorFinder' to the STATICFILES_FINDERS setting.

I tried to add compressor.finders.CompressorFinder but that gave me a similar error to above. So I ignored that. After some searching I found that I had to basically disable compressor (at least as I understand it) by adding this to settings.py:

COMPRESS_ENABLED = os.environ.get('COMPRESS_ENABLED', False)

This didn't completely fix the problem as then I was having issues locating the static files. So, I had to set my STATIC_ROOT to this:

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

Pushed to heroku and there you have it... Debug=False now working

GrantRWHumphries
  • 612
  • 7
  • 22
  • 6
    The most important thing is `DEBUG_PROPAGATE_EXCEPTIONS = True`. With that, you can see the errors in the log. – bmiljevic Aug 27 '19 at 13:31
  • 5
    You're the real MVP - whoever decided that DEBUG_PROPAGATE_EXCEPTION should default to False should be severely punished. – Giacomo Lacava Jan 27 '20 at 18:50
6
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'

helped in my case

Simon B
  • 101
  • 1
  • 3
  • This works!! note: instead of `STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'`
    from the answer down below too. [source](https://stackoverflow.com/a/66661021/13558882)
    – sutan Jan 19 '22 at 18:57
3

For me the issue was that I had commented HTML code block

<!-- 
Some reference to images.

-->

Collectstatic ignores images that are referenced within comment but there is a typical behaviour in Django processing when Debug=False is set which actually tries to parse and verify images within HTML comments (This does not happen when Debug=True is set).

When I removed comments, I was able to render the page and 500 error was gone.

Roshan Shah
  • 381
  • 2
  • 5
3

I was using white noise in my applications after removing this:

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

and adding this:

STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'

solved the problem

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Ankit Kumar
  • 389
  • 3
  • 9
1

The reason may be very silly it may be something like static files path names you provided in your templates. Let's see a example:
CODE-1

<img src="{% static '/images/Rectangle 2.png' %}" class="card-img-top" alt="..." >

CODE-2

<img src="{% static 'images/Rectangle 2.png' %}" class="card-img-top" alt="..." >

Both code1 and code2 will work properly when DEBUG=True. But if DEBUG=False code2 will work fine but code1 won't work. The extra slash(/) before images creates an issue, i.e., production can't configure the path properly.

So please have a look at your static file paths in your templates. That might be the issue.

0

Set DEBUG=False in .env file in django project, configure the DEBUG variable in settings to point to the variable in .env file. Add DEBUG = False to configs in Heroku. I don't know why this works but I'm glad it does.

mutiso
  • 1
  • 1
-1

STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'

Elhadj
  • 1