Django - Wagtail - Heroku: How to troubleshoot intermittent, seemingly random, HTTP 404s? - python

I'm serving Wagtail pages in a very well tested web app. No errors show up in development.
When in Production (using Heroku and a hobby-tier Postgres db), those pages occasionally return an HTTP 404. If I refresh the browser a couple times, it goes back to serving the Page perfectly again.
Some details:
This happens with multiple pages;
I get emails with the 404 error when this happens, so Django's BrokenLinkEmailsMiddleware is kicking in;
Heroku web Dyno looks healthy based on its metrics;
Heroku Postgres has no logs for the Hobby tier, so I don't know what's going on on the db side;
Server is running behind a Cloudflare proxy server, but I can see the request hitting the origin and returning a 404.
I'm obviously not expecting a solution here since the above info is insufficent for that. But I'm looking for troubleshooting pointers, for example:
If the db has become under-dimensioned (too little RAM, too many simultaneous connections, etc.) - could that result in a Wagtail db query wrongly returning PageNotFound? Or would that return a 500 Server Error?
How can I test DB error-handling locally with Django?
How can I add a full Traceback for the Django 404 error, so I'm able to know exactly what line of code raised it?
What are other potential causes of intermittent HTTP 404 errors?
Any help here is welcome!

Related

How can I handle subdomains with Flask, Cloudflare and Heroku?

I bought a domain, let's say its "mydomain.org".
I connected that domain to Cloudflare and Heroku, and I can access my web app(site) on mydomain.org, handle the flask's route('/') requests.
But when I use, for example, route('/', subdomain="test") and try to return "This is a subdomain", it does nothing, or if it does, it redirects me to the simple route('/') (so basically without the subdomain).
I registered a subdomain on Heroku and created an alias for test.mydomain.org to point to the DNS that Heroku gave me, but I still get redirected to the main page, instead of getting simply the "This is a subdomain" message.
How could I make it work?

Google App Engine Produces 502 Error on Python/Flask API

I've been all over google, and stack and read EVERY article I could find but have not been able to solve me issue. I recently wanted to take my project that is still in development and get it up on GAE so I could test it and make sure it would work as I assumed. After some trail and error I was able to get a Postgres database setup and push my project using
gcloud app deploy app.yaml
My Flask app is using Swagger and Flask-Restplus for the API. I can access the swagger page and perform some requests, however all of those requests come back with
502 Bad Gatway
While reading the live log in the console I can see the data is coming in as I would expect. There are no exceptions, and the GAE error console does not even log the 502 error. In the console I can also see..
[CRITICAL] WORKER TIMEOUT (pid:17)
So I went into the logs and see this NGINX error..
textPayload: "[error] 32#32: *4086 upstream prematurely closed connection while reading response header from upstream, client: 130.211.2.231, server: , request: "POST /auth/login_user HTTP/1.1", upstream: "http://172.17.0.1:8080/auth/login_user", host: "blah-191811.appspot.com", referrer: "http://blah-191811.appspot.com/""
I don't think it is an error connecting to my database because I can connect to the Postgres DB hosted on GAE from my local computer. I also have another API endpoint that just uses a google API to retrieve some info and that also produces a 502 error.
I am at my wits end, and honestly about to throw in the towel and try to get it going on AWS if I can't figure this out. Any help would be much appreciated.
EDIT WITH MORE INFO:
The problem still persists. However, I have two routes on my API that require a valid JWT header. When using these routes with an invalid header token, or no token the API returns the correct response, a 401. When sending the correct token the API again returns a 502. This makes me believe that there is nothing wrong with my code, but that somewhere the response is not getting sent back.
I should add that these are not data intensive calls. The login_user is just two strings, an email and a password. The database has only one entry in it.
When I run locally but CONNECT to the remote Postgres database the API works as expected. I.e if I run a Flask server locally and do; 127.0.0.1:5000/auth/login_user and send the correct information, it is able to read back from my Postgres database on my GAE project. So I don't believe the database is the issue either.
Still looking for any wisdom because this seems to be a very common issue with little resolve.
For anyone else experiencing this issue..I found the solution after much digging. It was in the way I was connecting to the potgres SQL instance on GAE.
I was using this;
SQLALCHEMY_DATABASE_URI = 'postgresql://user:password#remote.ip.addr/database_name'
This code works fine when you are accessing the SQL instance from a whitelisted IP. However this code will not work inside an instance that also runs on GAE. You need to change it to this;
SQLALCHEMY_DATABASE_URI = 'postgresql://user:password#/database_name?
host=/cloudsql/database_instance_id'

flask_login sometimes mixes logins; I'm logged in as somebody else

I'm using the awesome Flask framework to create a website in which I use Flask-login for my user logins. This normally works fine, but sometimes I see strange issues with logins being mixed. We've got 3 flask dev-servers running on one machine (on different ports) and we're working in an office with about 10 people (with one shared ip). The problem is that sometimes one user is suddenly logged in as another user.
I can't really pinpoint when or under which circumstances this happens. But I also don't really know how I can debug it. Could the source of the evil be that we share an internet connection or is the problem that we run several flask dev-servers on one machine?
I don't know whether this also happens with people outside of our office (we're still in testing phase).
Can anybody give me some tips on how I can debug this?
Most likely you are using a web server which is caching (some of ) HTTP replies from Flask. These could include static media, generated media, PDFs, Office files.
A misconfigured front end web server may cache such a HTTP response containing media and the session cookie (Cookies header). After happily caching this response then the front end web server serves it to another user. The existing session cookie of this user gets overwritten with the session cookie from the cached HTTP response. Then, due to session switch, the user becomes the user whose HTTP response was cached.
Solutions
Fix your session middleware
Explicitly set no caching headers on the server side
Configure your front end web server not to cache responses with cookies
Further information in operationssecurity.org.

Sentry AJAX requests get 302 with Nginx and uWSGI

I have Sentry setup almost exactly like described here.
My Sentry is available on www.sentry.mysite.com:9000, and everything working fine, except AJAX queries, for example by click on "resolve error" button. AJAX queries uses url without port, and they always get 302 status and they have no effect.
Kindly help.

AppEngine: Can I fetch an internal url?

Does anyone know, if I can fetch an internal AppEngine url from within my AppEngine app?
The official URL Fetch Python API doesn´t cover that.
http://code.google.com/intl/et-EE/appengine/docs/python/urlfetch/overview.html
I tried different possibilities, but as it seems nothing works. Does anyone did that before?
urllib2.urlopen('http://127.0.0.1:8080/start_something/')
or
urllib2.urlopen('/start_something/')
...
Thanks in advance.
This will not work at all with the development server. It is single-threaded, so trying to load one of your app's URL's while inside one of its request handlers will hang until the URLFetch times out.
It should work with no problems at all in production.
To get around the development server limitation, you should run two instances on different ports.

Categories