4

I've been using HttpResponseBadRequest (http 400) quite a bit in Django recently. I became curious about what it means exactly, and I came across this question. According to the accepted answer there it sounds like using HttpResponseBadRequest in a view is always wrong by definition.

I use it for situations where a view receives incorrect input or is called under the wrong circumstances, which could only be caused by a user with bad intentions entering bad data (or from bugs in my code).

The alternative HttpResponses all seem like worse choices in this case. How is HttpResponseBadRequest used by most Django developers? The documentation doesn't seem to explain what to use the different classes for.

Community
  • 1
  • 1
Lundis
  • 311
  • 2
  • 11
  • 1
    If you have trolls, don't feed them. Not even with an exotic status code... 404 and ignore. ;) – allcaps Dec 02 '14 at 00:05

2 Answers2

2

This is not specific to Django. What you are really asking is when to use an HTTP 400 ("Bad Request") status code. In general, any page that you successfully render to the user should get a 200-level code. Any request where there is a server-side failure should get a 500-level code. The 400-level codes are intended for cases where the request failed but was due to a client rather than server error. For example, the 404 is for a case where the URL corresponds to a path that does not exist on the server.

A typical case where one uses a 400 status code is for an HTTP request that gets sent to a valid, supported path, where the request parameters (e.g. the GET or POST parameters) are incorrect (required parameters are missing or parameters have values that are not of the right type, not in the allowed ranges, or not a valid enum value in the case of enum parameters). This should pretty much never happen in a user-issued request (since other parts of your application should generate only well-formed requests) and is significantly more common for APIs that you create for other developers (or for yourself). That is, if a request is failing and you see it is a 400, you can pretty quickly diagnose that the parameters need to be altered for it to work correctly. If that's what you mean by "where a view receives incorrect input", then that seems reasonable to me; however, "under the wrong circumstances" seems like an incorrect usage of a 400 status code. For the "under the wrong circumstances" case, there may be more appropriate status codes, depending on what you mean by "the wrong circumstances".

I should emphasize, however, that there is no exact right answer. When choosing which error codes to use, important considerations include: internal consistency between resources within the same site, understandibility/expectation by developers using your API (if you are creating an API), how the various status codes are interpreted by the browser, proxies, and search engines.

Michael Aaron Safyan
  • 87,518
  • 14
  • 130
  • 194
  • By circumstances, I mean that I have users that can be in two states (A and B). Any links to a page are only shown when the user is in state A. If a user in state B ends up visiting the page, he/she must have entered the URL manually, which IMO is a fault with the client. I suppose a 404 would also make sense in that case. – Lundis Dec 01 '14 at 21:22
  • A 404 isn't quite appropriate. Forbidden might be more appropriate for that. – Michael Aaron Safyan Dec 02 '14 at 06:08
1

Apparently the recommended way of handling impossible/strange user input is not to return HttpResponseBadRequest explicitly, but to instead use a SuspiciousOperation exceptions. They in turn result in a HttpResponseBadRequest and some extra logging. So, in the context of the example in my question, a 400 status code would be the way to go in Django.

Lundis
  • 311
  • 2
  • 11