Reputation: 1238
The default message for Flask 400
exception (abort()
) is:
{
"message": "The browser (or proxy) sent a request that this server could not understand."
}
For 404
:
{
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. You have requested this URI [/obj/] but did you mean /obj/ or /obj/<int:id>/ or /obj/<int:id>/kill/ ?"
}
I have trouble comprehending these messages when I'm getting them as replies in my API (especially the first one, I thought there's something wrong with encryption or headers) and I thing it's kinda tiresome to try to override text manually for every abort()
exception. So I change the mapping:
from flask import abort
from werkzeug.exceptions import HTTPException
class BadRequest(HTTPException):
code = 400
description = 'Bad request.'
class NotFound(HTTPException):
code = 404
description = 'Resource not found.'
abort.mapping.update({
400: BadRequest,
404: NotFound
})
For the case of 400
it works beautifully. But when it comes to 404
it is still the same message. I tested it in the same place in my code - it works for abort(400)
, abort(403)
and some of the others, but it gets mysteriously overridden by default message on abort(404)
. Debugging didn't help much. What may be the culprit here?
Update. Yes, I'm using abort
imported from flask
not flask_restful
as the latter doesn't have the mapping and it's a function not an Aborter
object. Besides, it does work for most exceptions, so it's probably not the real issue here.
Update 2. The abort.mapping
seems to be perfectly fine on execution. The exceptions in question are overridden, including 404
.
Update 3: I've put together a little sandbox, that I use for debugging. (removed the repo since the mystery is long solved).
Upvotes: 6
Views: 6154
Reputation: 81
By the way... I can't point to documentation for how I discovered this, I just tried it (that's how I learn most development!) but, you can simply abort with the desired response code but instead return a custom string with it. I think this makes sense because you're using the framework the way it's intended, you're not writing tons of code, you're returning the correct response code and in the fashion the framework expects, and you're informing any human who reads it as to the application's context for the error.
from flask import abort
abort(404, "And here's why.")
Upvotes: 2
Reputation: 1238
It took me some time, but now I actually found the place, where it all derails on 404
error. It's actually an undocumented feature in flask-restful. Look at the code here. Whatever message you chose persists until that very place and then it becomes the default. What we need now is just put ERROR_404_HELP = False
to our config and everything works as intended.
Why is this code even there in the first place? OK, perhaps, I can live with that, but it should be all over the documentation. Even when I googled the name of the constant, I only got a couple of GitHub issues (1, 2).
Anyways, the mystery is officially solved.
Upvotes: 5