代码之家  ›  专栏  ›  技术社区  ›  amanb

针对不正确的收割台烧瓶引发自定义异常

  •  -3
  • amanb  · 技术社区  · 8 年前

    我正在构建一个烧瓶REST API,它还没有前端。我已经成功开发了一个针对Flask视图的GET请求,该视图从SQL数据库中获取所有订阅服务器。我使用相同的烧瓶视图 INSERT VALUES 通过对数据库的POST请求。为了清理输入,我使用了 (%s) 作为值的占位符。以下是代码摘录:

    #main.py
    @app.route('/api/subscribe/', methods=['GET', 'POST'])
    def subscribe():
        if request.method == 'GET':
            try:
                data = DB.get_subscription_list()
                return Response(json.dumps({'result': data}, cls=DateTimeEncoder, sort_keys=True), mimetype='application/json')
            except Exception as e:
                return e
        elif request.method == 'POST':
            try:
                email = request.form.get('email')
                data = DB.add_email(email)
                return Response(json.dumps({'result': 'Email added to database'}, cls=DateTimeEncoder, sort_keys=True), mimetype='application/json')
            except Exception as e:
                return e
    
    
    #dbhelper.py
    def add_email(self,data):
        connection = self.connect()
        try:
            #The following adds an email entry to the 'users' table.
            query = "INSERT INTO users (email) VALUES (%s);"
            with connection.cursor() as cursor:
                cursor.execute(query,data)
                connection.commit()
        except pymysql.ProgrammingError as e:
            print(e)
            raise e   
        finally:
            connection.close()
    

    我用更精确的信息编辑了这个问题,并针对我的问题。

    我目前正在RESTClient和Postman上测试API。

    当我发送带有标题的POST请求时 {'Content-Type':'application/x-www-form-urlencoded'} ,值插入成功。输出: {"result": "Email added to database"} 。如果未使用此标头,则会出现以下Programmingerror异常:

    (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s)' at line 1")

    如何为不正确的标头条目引发自定义异常,使其引发此自定义异常,而不是显示语法错误?当然,这不是语法错误,因为在使用 URL编码 标题。

    1 回复  |  直到 8 年前
        1
  •  0
  •   eyllanesc    8 年前

    我通过为每个错误状态代码创建自定义错误处理程序解决了这个问题。我意识到 模拟类型 {'Content-Type':'application/x-www-form-urlencoded'} 使用时需要标题 request.form.get() 。这是因为表单中的信息在发送到服务器时是经过编码的。我现在使用 request.json.get() 因为我想发送数据 json 相反,现在需要的标题是 {'Content-Type':'application/json'} 模拟类型 。现在我的观点是这样的:

    #subscribe.py
    @app.route('/api/users/subscribe', methods=["GET", "POST"])
    def subscribe():
        if request.method == "GET":
            try:
                data = DB.get_subscription_list()
                return Response(json.dumps({'result': data}, cls=DateTimeEncoder, sort_keys=True), mimetype='application/json', status=200)
            except Exception:
                return Response(json.dumps({'error': 'Could not fetch subscribers from database.'}), status=500)
        elif request.method == "POST":
            try:
                email = request.json.get("email")
                data = DB.add_email(email)
                return Response(json.dumps({'result': 'Email added to database.'}, cls=DateTimeEncoder, sort_keys=True), mimetype='application/json', status=201)
            except Exception:
                return Response(json.dumps({'error': 'Could not add to database.'}), status=500)
    

    请注意,上述每个方法的自定义错误异常。我还创建了自定义错误处理程序,以防出现带有状态代码的错误,并且我还没有为它们明确定义异常。例如,如果我得到一个状态代码为500的错误 html ,下面的错误处理程序将在中显示自定义错误 json 。我已经为状态码405、401等添加了类似的错误处理程序,以便在 json 。

    @app.errorhandler(500)
    def method_not_allowed(error):
        return make_response(jsonify({'error': 'An error occurred during a request'}), 500)
    

    类似地,我为数据库查询添加了一个例外:

    #dbhelper.py
    try:
        #The following adds an email entry to the 'users' table.
        uri = url_for('subscribe', email=email, _external=True)
        query = "INSERT INTO users (email) VALUES (%s);"
        with connection.cursor() as cursor:
            cursor.execute(query,email)
            connection.commit()
    except Exception:  
        return Response(json.dumps({'error':'Database connection error.'}), status=500)
    

    现在,我 json 当我没有以json格式发送数据或在POST请求中发送无效数据时出现异常。没有 Programmingerrors 我已经更正了代码,以获得期望的结果。

    一种更有条理的方法是在单独的 errors.py 文件并在必要时调用异常函数。

    推荐文章