英文:
How do I interpret PostgreSQL error messages from within Go?
问题
如何在Go语言中解析SQL约束错误,特别是由于UNIQUE
、FOREIGN KEY
、NOT NULL
、ON 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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论