skip to Main Content

I am new to Flask, which is required for this school project.

I thought I would display an error page if something unexpected happened.

I have tried several approaches.

The latest attempt produces this error:
TypeError: The view function for ‘get_data’ did not return a valid response. The function either returned None or ended without a return statement.

I assume my ‘redirect(url_for("error"))’ statement is misplaced.

How would I display the error page, please?

main.py:

from flask import Flask, render_template, request, redirect, url_for
import os

app = Flask(__name__)

class Api:
    def get_api_key():

        try:
            api_key = os.environ.get('this_key_does_not_exist')
            raise ValueError(f"Invalid value: key not found")

        except TypeError as e:
            return redirect(url_for("error"))

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/get_data", methods=["POST"])
def get_data():
    if request.method == "POST":
        api = Api()
        api.get_api_key

@app.route("/error")
def error():
    return render_template("error.html")

if __name__ == "__main__":
    app.run()

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  <title>Example</title>
</head>
<body>
   <form action="{{ url_for('get_data') }}" method="POST">
        <label>Please submit</label>
        <input type="submit" value="Submit">
   </form>
</body>
</html>

error.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  <title>Example</title>
</head>
<body>
   <p>An unexpected error has occurred.</p>
   <br />
   <p>For assistance, please call 9999 999 999</p>
</body>
</html>

3

Answers


  1. Chosen as BEST ANSWER

    Problem solved for now. I updated main.py thus:

    from flask import Flask, render_template, request, redirect, url_for
    import os
    
    app = Flask(__name__)
    
    class Api:
        def get_api_key(self):
            try:
                api_key = os.environ.get('this_key_does_not_exist')
                if not api_key:
                    raise ValueError(f"Invalid value: key not found")
            except ValueError as e:
                # Redirect to the error route
                return redirect(url_for("error"))
            else:
                return redirect(url_for("index"))
    
    
    @app.route("/")
    def index():
        return render_template("index.html")
    
    @app.route("/get_data", methods=["POST"])
    def get_data():
        #if request.method == "POST":
        api = Api()
        # You need to call the method, not just reference it
        return api.get_api_key()
    
    @app.route("/error")
    def error():
        return render_template("error.html")
    
    if __name__ == "__main__":
        app.run()
    

  2. The error you’re seeing is because of the fact that your get_data function does not return a valid response (in your case, it does not return anything, since you are not calling the method).

    There are a few issues with this design:

    • You don’t need to check request.method == "POST", since it’ll be handled by Flask automatically due to the decorator’s arguments.
    • To define custom error pages/responses, you can use Flask’s error handlers. Here are the docs along with some examples.
    Login or Signup to reply.
  3. You seem to have a misunderstanding what the return statement does:

    When there is a return statement in a route, the API will make it a response for the client

    @app.route("/get_data", methods=["POST"])
    def get_data():
        return  # will make a response
    

    A return statement in a class method will not trigger a response for the client, it will only return the result to the caller, which in this case is to the route – not to the client.

    class Api:
        def get_api_key():
            return  # will only complete the function call. the control flow will be returned to the function caller (which still needs to make a real response)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search