During development, I am running Django in Debug mode and I am posting data to my application using a text mode application. Ideally, I need to receive a plain text response when I get an http error code 500 so I don't have to look for the real error inside all that HTML and Javascript.
Is it possible to obtain a Django 500 Internal Server Error as plain text?
If you are looking for a way to get a plain text error page when using curl
, you
need to add the HTTP header X-Requested-With
with value XMLHttpRequest
, e.g.
curl -H 'X-Requested-With: XMLHttpRequest' http://example.com/some/url/
Explanation: this is because Django uses the is_ajax
method to determine whether or not to return as plain text or as HTML. is_ajax
in turn looks at X-Requested-With
.
Since django version 3.1, error reporting ignores the X-Requested-With
header. Instead, set the Accept
header on the request to any valid value which does not include the text/html
mime type.
e.g.
curl -H 'Accept: application/json;charset=utf-8' http://example.comp/some/url
This is an improvement on Yuji's answer, which provides a stacktrace, more instructions (for us django newbies) and is simpler.
Put this code in a file somewhere in your application, e.g. PROJECT_ROOT/MAIN_APP/middleware/exceptions.py
, and make sure you have an empty __init__.py
in the same directory.
import traceback
from django.http import HttpResponse
class PlainExceptionsMiddleware(object):
def process_exception(self, request, exception):
return HttpResponse(traceback.format_exc(exception), content_type="text/plain", status=500)
Now edit your settings.py
and find MIDDLEWARE_CLASSES = (
. Add another entry so it is like this:
MIDDLEWARE_CLASSES = (
# (all the previous entries)
# Plain text exception pages.
'MAIN_APP.middleware.exceptions.PlainExceptionsMiddleware',
)
Restart django and you are good to go!
If you're like me and developing an app and a website both backed by django, you probably want to show plain text error pages to the app, and the nice formatted ones to the browser. A simple way to to that is to check the user agent:
import traceback
from django.http import HttpResponse
class PlainExceptionsMiddleware(object):
def process_exception(self, request, exception):
if "HTTP_USER_AGENT" in request.META and "chrome" in request.META["HTTP_USER_AGENT"].lower():
return
return HttpResponse(traceback.format_exc(exception), content_type="text/plain", status=500)
I think to write a middleware, because otherwise the exception isn't available in the 500.html
http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception
class ProcessExceptionMiddleware(object):
def process_exception(self, request, exception):
t = Template("500 Error: {{ exception }}")
response_html = t.render(Context({'exception' : exception }))
response = http.HttpResponse(response_html)
response.status_code = 500
return response
There's a setting DEBUG_PROPAGATE_EXCEPTIONS which will force Django not to wrap the exceptions, so you can see them, e.g. in devserver logs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With