如何在Go语言中解释PostgreSQL的错误信息?

huangapple go评论93阅读模式
英文:

How do I interpret PostgreSQL error messages from within Go?

问题

如何在Go语言中解析SQL约束错误,特别是由于UNIQUEFOREIGN KEYNOT NULLON DELETE RESTRICT等约束引起的错误?

例如,在数据库中定义了一个UNIQUE字段的情况下,插入一个可能具有相同电子邮件的新用户。在Go中解析约束错误,并将错误返回给浏览器客户端。

英文:

How can I parse SQL constraint errors, in particular resulting from constraints such as UNIQUE, FOREIGN KEY, NOT NULL, ON DELETE RESTRICT within Go?

e.g. Insert a new user that may have the same email which is defined as a UNIQUE field in the database. Parse constraint error in Go, return error to browser client.

答案1

得分: 6

有关如何解释来自github.com/lib/pq的错误的信息,请参阅http://godoc.org/github.com/lib/pq#Error。

这是我要做的:

// ShowError发送适当的错误消息。
func ShowError(w http.ResponseWriter, r *http.Request, err error) {
switch e := err.(type) {
case *pq.Error:
switch e.Code {
case "23502":
// not-null constraint violation
http.Error(w, fmt.Sprint("Some required data was left out:\n\n", e.Message), http.StatusForbidden)
return

    case "23503":
        // foreign key violation
        switch r.Method {
        case "DELETE":
            http.Error(w, fmt.Sprint("This record can’t be deleted because another record refers to it:\n\n", e.Detail), http.StatusForbidden)
            return
        }

    case "23505":
        // unique constraint violation
        http.Error(w, fmt.Sprint("This record contains duplicated data that conflicts with what is already in the database:\n\n", e.Detail), http.StatusForbidden)
        return

    case "23514":
        // check constraint violation
        http.Error(w, fmt.Sprint("This record contains inconsistent or out-of-range data:\n\n", e.Message), http.StatusForbidden)
        return

    default:
        msg := e.Message
        if d := e.Detail; d != "" {
            msg += "\n\n" + d
        }
        if h := e.Hint; h != "" {
            msg += "\n\n" + h
        }
        http.Error(w, msg, http.StatusInternalServerError)
        return
    }

case *strconv.NumError:
    http.Error(w, fmt.Sprintf(`"%s" is not a valid number.`, e.Num), http.StatusBadRequest)
    return

default:
    switch err {
    case sql.ErrNoRows:
        http.NotFound(w, r)
        return
    }
}

http.Error(w, err.Error(), http.StatusInternalServerError)

}

英文:

For information about how to interpret errors from github.com/lib/pq, see http://godoc.org/github.com/lib/pq#Error.

Here is what I do:

// ShowError sends an appropriate error message.
func ShowError(w http.ResponseWriter, r *http.Request, err error) {
	switch e := err.(type) {
	case *pq.Error:
		switch e.Code {
		case "23502":
			// not-null constraint violation
			http.Error(w, fmt.Sprint("Some required data was left out:\n\n", e.Message), http.StatusForbidden)
			return

		case "23503":
			// foreign key violation
			switch r.Method {
			case "DELETE":
				http.Error(w, fmt.Sprint("This record can’t be deleted because another record refers to it:\n\n", e.Detail), http.StatusForbidden)
				return
			}

		case "23505":
			// unique constraint violation
			http.Error(w, fmt.Sprint("This record contains duplicated data that conflicts with what is already in the database:\n\n", e.Detail), http.StatusForbidden)
			return

		case "23514":
			// check constraint violation
			http.Error(w, fmt.Sprint("This record contains inconsistent or out-of-range data:\n\n", e.Message), http.StatusForbidden)
			return

		default:
			msg := e.Message
			if d := e.Detail; d != "" {
				msg += "\n\n" + d
			}
			if h := e.Hint; h != "" {
				msg += "\n\n" + h
			}
			http.Error(w, msg, http.StatusInternalServerError)
			return
		}

	case *strconv.NumError:
		http.Error(w, fmt.Sprintf(`"%s" is not a valid number.`, e.Num), http.StatusBadRequest)
		return

	default:
		switch err {
		case sql.ErrNoRows:
			http.NotFound(w, r)
			return
		}
	}

	http.Error(w, err.Error(), http.StatusInternalServerError)
}

huangapple
  • 本文由 发表于 2015年4月30日 02:24:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/29951615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定