根据错误显示自定义的异常消息

时间:2016-12-06 04:33:36

标签: python mysql database

我希望我的代码显示一个自定义错误消息,该消息取决于它遇到的错误类型。

from .forms import NameForm, IdForm
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from client_storage import insert
import mysql.connector.errors
from mysql.connector.errors import Error
import MySQLdb


def sign_in(request):
        #we need to handle all the data that was just typed, we'll add a condition for that
        if request.method == "POST":
            #here will construct the form with the POST data
            form = NameForm(request.POST)
            #the next part is to check that the information submitted is valid
            if form.is_valid():
                post = form.save()
                post.save()
                return HttpResponse(post.question_text)
            else:
                return HttpResponse("Form is invalid")
        else:
            form = NameForm()
        return render(request, 'checkin/base.html', {'form': form})

    #this view will be the sign-up view, where new clients will be given new ID numbers for training

def sign_up(request):

    if request.method == "POST":
        form = IdForm(request.POST)
        if form.is_valid():
            post = form.save()
            post.save()
            ID = post.id_text
            #we'll call an external function that checks membership of the users input in the database
            # query is the first element of the tuple that is returned from insert()
            query = insert(post.id_text)
            if query == 1062:
                messages.add_message(request, messages.INFO, 'Already taken ')
                return HttpResponseRedirect('sign_up')
            if query == 1054:
                messages.add_message(request, messages.INFO, 'Invalid input')
                return HttpResponseRedirect('sign_up')
            else:
                messages.add_message(request, messages.INFO, 'Thank you for signing up!')
                return HttpResponseRedirect('sign_up')

            # if the user enters a number that is already in use raise an 'duplicate' error
            # Capture the exception here
        else:
            return HttpResponse('That text is invalid')
    else:
        form = IdForm()
    return render(request, 'checkin/base.html', {'form': form})

For the `except` block I'm trying to figure out how to display either "Already taken" or "Invalid input" depending on the error code. However only "Already taken" ever appears. I feel like the problem is that the exception is being thrown before it even gets to the `if` clauses?

我正在为INSERT进程使用另一个文件:

import MySQLdb
import mysql.connector
from mysql.connector import errorcode
from django.contrib import messages

#Use a function to insert new information into the database

def insert(info):
    #open a connection
    db = MySQLdb.connect('localhost','root','password', 'CLIENTS')
    #prepare a cursor
    cursor = db.cursor()
    #prepare SQL query
    sql = "INSERT INTO clients(ID) VALUES (%s)" % info

    try:
        #execute the command
        cursor.execute(sql)
        #commit changes to the database
        print 'success'
        db.commit()
    except MySQLdb.Error as e:
        #return the first element in the tuple that contains the error message, which will be the errorcode
         if e[0] == 1062:
            return e[0]
         if e[0] == 1054:
            return e[0]

    #disconnect from server
    db.close()

编辑问题似乎是我使用mysql.connector.error代替MySQLdb.Errormysql网站似乎只使用前者。并且似乎没有很多关于后者的官方文档,但幸好我发现this site.我更改了代码,因此sign_in视图将从外部returned信息中获取insert信息{1}}然后采取行动。

1 个答案:

答案 0 :(得分:1)

与@wwii在评论中所说的一样,您需要编辑try ... except块以捕获异常。请参阅documentations的此页。

此外,在您的实际代码Error(errno=1062)中,始终返回一个非零字符串,用于验证您的if语句。这就是为什么你总是得到Already Taken消息。

为了解决这个问题,您应该将代码修改为以下示例:

# What you need to import
import mysql.connector
from mysql.connector import errorcode

try:
    insert(post.id_text)
    messages.add_message(request, messages.INFO, 'Thank you for signing up ')
    return HttpResponseRedirect('sign_in')

# Catch the error exception
except mysql.connector.Error as err:
    # Error code 1062: https://dev.mysql.com/doc/refman/5.6/en/error-messages-server.html#error_er_dup_entry
    if err.errno == errorcode.ER_DUP_ENTRY:
        messages.add_message(request, messages.INFO, "Already taken") 
        return HttpResponseRedirect('sign_up')

    # Error code 1054: https://dev.mysql.com/doc/refman/5.6/en/error-messages-server.html#error_er_bad_field_error
    if err.errno == errorcode.ER_BAD_FIELD_ERROR:
        messages.add_message(request, messages.INFO, "Invalid input")
        return HttpResponseRedirect('sign_up')

修改

您在Python2Python3内修改的答案都是正确的。

否则,如果您使用Python2,则可以执行此类操作。

try:
    #execute the command
    cursor.execute(sql)
    #commit changes to the database
    print 'success'
    db.commit()
except MySQLdb.Error, e:
     if e.args[0] == 1062 or e.args[0] == 1054:
        # e.args[0] is the error code in int format
        # e.args[1] is the complete error message in str format
        return e.args[1]
     else:
        # I didn't test all the cases, but this message
        # can save you more time during the debug later
        # if your code catch another error code rather than 1062 or 1054
        return "Something odd happened"

此外,您可以执行以下操作(此示例适用于Python2Python3):

try:
    #execute the command
    cursor.execute(sql)
    #commit changes to the database
    print 'success'
    db.commit()
except MySQLdb.Error as e:
     if e[0] == 1062 or e[0] == 1054:
        # e[0] is the error code in int format
        # e[1] is the complete error message in str format
        return e[1]
     else:
        # Good for the debug
        return "Something odd happened"