9

I am working on a simple Flask REST API test and when I call the {{url}}/items for example I get the items list. However if a call is passed to an endpoint that does not exist for example {{url}}/itemsss then I get the error 404 in html.

I would like to make the error handling more friendly and return json instead of html for certain errors such as 400, 404,405...

For the 404 for example i tried this:

@app.errorhandler(404)
def not_found(e):
    response = jsonify({'status': 404,'error': 'not found',
                        'message': 'invalid resource URI'})
    response.status_code = 404
    return response

However it does not work.

My issue is similar to this one: Python Flask - Both json and html 404 error

I wanted to know, if using the blueprints the only way to accomplish this?

If there a simpler way to output the 404 error as json?

For example instead of this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<title>404 Not Found</title>

<h1>Not Found</h1>

<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>

Something like this:

{

error: true,

status: 404,

code: "error.notFound",

message: "API endpoint not found",

data: { }

}

I appreciate your help with this.

4 Answers 4

14

Usually when I need to return a custom error message with Flask-RESTful I would do something like:

from flask import make_response, jsonify

def custom_error(message, status_code): 
    return make_response(jsonify(message), status_code)
Sign up to request clarification or add additional context in comments.

Comments

7

I think I found the solution in the official documentation:

from flask import json
from werkzeug.exceptions import HTTPException

@app.errorhandler(HTTPException)
def handle_exception(e):
    """Return JSON instead of HTML for HTTP errors."""
    # start with the correct headers and status code from the error
    response = e.get_response()
    # replace the body with JSON
    response.data = json.dumps({
        "code": e.code,
        "name": e.name,
        "description": e.description,
    })
    response.content_type = "application/json"
    return response

Comments

3

Code and description are there in HTTP anyways, need only the message. And using jsonify from flask.

from flask import jsonify
from werkzeug.exceptions import HTTPException

@app.errorhandler(HTTPException)
def handle_exception(e):
    return jsonify({"message": e.description}), e.code

Comments

1

This works and is simpler than all of the other answers:

return {}, 404

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.