Friday, December 22, 2017

Re: Response is None in exception handling?

I have had a bit of bother because the project was written for django 1.4 and uses quite a few plugins, some of which are not actively maintained. Mostly the errors are easily traced, but this middleware issue doesn't raise helpful errors. Maybe there's something I can add to help, we should be able to inform devs if middleware returns none quite easily. 


Sent from my Samsung Galaxy smartphone.
-------- Original message --------
From: Jason <jjohns98684@gmail.com>
Date: 2017/12/22 13:20 (GMT+00:00)
To: Django users <django-users@googlegroups.com>
Subject: Re: Response is None in exception handling?

Interesting solution, and thanks for posting the solution for others to find.

You've been having an adventure updating, haven't you?


On Thursday, December 21, 2017 at 8:31:59 PM UTC-5, Andrew Buchan wrote:
Hi Jason,

The stack was all just the normal stuff that happens, all of which is Django code, except for the bit about processing middleware, so I disabled what I could of those,, and indeed it was middleware classes which had been badly upgraded.

The middleware classes used to have a process_request method, but now need a __call__ method instead, which looks like the same deal, except it seems that a middleware class's __call__ method must return a response object, whereas process_request could return None.

#Olds style:

class TermsMiddleware(object):

    def process_request(self, request):
        if not request.user.is_anonymous and not request.user.profile.has_read_tcs:
            return redirect('read_and_sign_tc')
        #note how it returns None

# New style
class TermsMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        if not request.user.is_anonymous and not request.user.profile.has_read_tcs:
            return redirect('read_and_sign_tc')
        return response


Thanks for your help!

Andrew

On Friday, December 22, 2017 at 12:14:39 AM UTC, Jason wrote:
what I would do is put a breakpoint at 

  File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/core/handlers/exception.py", line 35, in inner
   response = get_response(request)

and follow the method call stack.  

Questions:
  1. what is response in the exception context there?
  2. are you able to see what triggers that exception>=?


On Thursday, December 21, 2017 at 11:10:13 AM UTC-5, Andrew Buchan wrote:
I'm upgrading from Django 1.11 to Django 2.0 and getting the following error trying to load any page:

Internal Server Error: /favicon.ico
Traceback (most recent call last):
 File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/core/handlers/exception.py", line 35, in inner
   response = get_response(request)
 File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/utils/deprecation.py", line 97, in __call__
   response = self.process_response(request, response)
 File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/middleware/clickjacking.py", line 26, in process_response
   if response.get('X-Frame-Options') is not None:
AttributeError: 'NoneType' object has no attribute 'get'
[21/Dec/2017 15:19:10] "GET /favicon.ico HTTP/1.1" 500 74215

Or, if I disable that middleware, I get this:

Internal Server Error: /favicon.ico
Traceback (most recent call last):
  File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/utils/deprecation.py", line 97, in __call__
    response = self.process_response(request, response)
  File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/contrib/sessions/middleware.py", line 45, in process_response
    patch_vary_headers(response, ('Cookie',))
  File "/home/andrew/projects/healthmatters/website/env/lib/python3.5/site-packages/django/utils/cache.py", line 285, in patch_vary_headers
    if response.has_header('Vary'):
AttributeError: 'NoneType' object has no attribute 'has_header'

This happens for / and for /favicon.ico. It seems like there is no response object by the time it hits this middleware, and indeed, adding a print statement in my view for / shows it's get() method isn't even being called. I think an exception is happening somewhere, but the attempt to render the 500 page is having issues because the middleware is saying response is None.

So I've no idea what exception is causing it this time...

Here's what the bit in urls.py looks like:

baseurls = [
   url(r'^$', landing_views.LandingPageView.as_view(), name='landing_page'),
   ...
]

urlpatterns = baseurls + 
        static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Here's some settings:


MIDDLEWARE
= (
   'db_multitenant.middleware.MultiTenantMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'corsheaders.middleware.CorsMiddleware',
   'django.middleware.common.CommonMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   #'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
   'django.middleware.clickjacking.XFrameOptionsMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'corsheaders.middleware.CorsPostCsrfMiddleware',
   'easytz.middleware.TimezonesMiddleware',
   'impersonate.middleware.ImpersonateMiddleware',
   'apps.biomarker.middleware.SubscriptionMiddleware',
   'apps.biomarker.middleware.SuperuserMiddleware',
   'apps.practice.middleware.TermsMiddleware',
)

TEMPLATES = [
   {
       'BACKEND': 'django.template.backends.django.DjangoTemplates',
       'DIRS': [
           os.path.join(BASE_DIR, 'apps/templates'),
       ],
       'APP_DIRS': True,
       'OPTIONS': {
           'context_processors': [
               'django.contrib.auth.context_processors.auth',
               'django.template.context_processors.request',
               'django.template.context_processors.i18n',
               'apps.postman.context_processors.inbox',
               'apps.biomarker.context_processors.base_template_for_user_type',
               'apps.menus.context_processors.menu_elements',
               'django.template.context_processors.tz',
               'django_settings_export.settings_export',
               'apps.hm_multitenancy.context_processors.include_tenant'
           ]
       },
   },
]


--
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/zJP_DCvYKeA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/a89d1bef-d7eb-4b4a-ac84-69264075ed94%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment