Return api 响应中的 postgres 错误
Return postgres errors in api response
我的代码中有两个简单的 api 方法。端点 /api/user/create
的方法创建用户。字段 username
是唯一的。当我尝试使用数据库中已存在的相同用户名创建用户时,控制台出现错误:
(/home/andrej/go/src/go_contacts/models/users.go:19)
[2020-12-23 22:03:10] pq: duplicate key value violates unique constraint "users_username_key"
我想显示此错误以响应用户,或以某种方式识别我的代码中的错误类型,以向用户显示不同的错误消息。我只知道如果我有错误 user
returns 我的 id=0。但这对用户来说似乎不是一个好消息。
main.go
package main
import (
"fmt"
"go_contacts/controllers"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)
func main() {
godotenv.Load(".env")
router := mux.NewRouter()
router.HandleFunc("/", controllers.ReturnHello).Methods("GET")
router.HandleFunc("/api/user/create", controllers.CreateUser).Methods("POST")
port := os.Getenv("PORT")
if port == "" {
port = "8000"
}
err := http.ListenAndServe(":"+port, router)
if err != nil {
fmt.Print(err)
}
}
models.go
用户结构:
package models
import (
u "go_contacts/utils"
"github.com/jinzhu/gorm"
)
// User base model
type User struct {
gorm.Model
Username string `json:"username" gorm:"unique"`
Password string `json:"password"`
Email string `json:"email"`
}
// Create new user
func (user *User) Create() map[string]interface{} {
GetDB().Create(user)
if user.ID <= 0 {
return u.Message(false, "Failed to create user, connection error.")
}
response := u.Message(true, "Account has been created")
response["user"] = user
return response
}
根据评论gorm provides access to database errors from the Create record函数如下:
result := GetDB().Create(user)
if result.Error != nil {
// Do something with the error
}
请注意,检查错误字符串可能会使您的应用程序数据库变得特定(但这对您来说可能不是问题)。 this question 的答案可能会提供进一步的帮助。
至于 pq v1.5.2 和 gorm v1.9.12
首先需要判断create method call returns是否出错。像这样
err := GetDB().Create(user).Error
if err != nil {
// code to handle error
}
然后 pq 包有映射到 postgres 服务器错误的特殊类型。它包含可以帮助您识别错误严重性的字段、它的代码、与错误相关的 table 等
psql 字段标识符的完整列表可在此处找到
Error and Notice Message Fields
https://www.postgresql.org/docs/current/protocol-error-fields.html
要解决您的问题,我们可以使用字段
Code
这是错误代码的字符串类型表示。但首先,我们需要转换一个错误并检查类型转换是否成功。像这样
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// code to handle specific error code
}
错误代码列表可以在官方 postgresql 文档中找到 https://www.postgresql.org/docs/9.3/errcodes-appendix.html
并且实际 go pq 特定映射到 github.com/lib/pq/error.go as for pq library
中的错误
最后我们可以通过代码处理重复的错误
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// note that type casting here is redundant and used for showing specific
// string type from pq library
if pqErr.Code == pq.ErrorCode("23505") { // 23505 is unique_violation error code for psql
// now you can create error and write it to a message to return it for
// a client
}
}
我的代码中有两个简单的 api 方法。端点 /api/user/create
的方法创建用户。字段 username
是唯一的。当我尝试使用数据库中已存在的相同用户名创建用户时,控制台出现错误:
(/home/andrej/go/src/go_contacts/models/users.go:19)
[2020-12-23 22:03:10] pq: duplicate key value violates unique constraint "users_username_key"
我想显示此错误以响应用户,或以某种方式识别我的代码中的错误类型,以向用户显示不同的错误消息。我只知道如果我有错误 user
returns 我的 id=0。但这对用户来说似乎不是一个好消息。
main.go
package main
import (
"fmt"
"go_contacts/controllers"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)
func main() {
godotenv.Load(".env")
router := mux.NewRouter()
router.HandleFunc("/", controllers.ReturnHello).Methods("GET")
router.HandleFunc("/api/user/create", controllers.CreateUser).Methods("POST")
port := os.Getenv("PORT")
if port == "" {
port = "8000"
}
err := http.ListenAndServe(":"+port, router)
if err != nil {
fmt.Print(err)
}
}
models.go
用户结构:
package models
import (
u "go_contacts/utils"
"github.com/jinzhu/gorm"
)
// User base model
type User struct {
gorm.Model
Username string `json:"username" gorm:"unique"`
Password string `json:"password"`
Email string `json:"email"`
}
// Create new user
func (user *User) Create() map[string]interface{} {
GetDB().Create(user)
if user.ID <= 0 {
return u.Message(false, "Failed to create user, connection error.")
}
response := u.Message(true, "Account has been created")
response["user"] = user
return response
}
根据评论gorm provides access to database errors from the Create record函数如下:
result := GetDB().Create(user)
if result.Error != nil {
// Do something with the error
}
请注意,检查错误字符串可能会使您的应用程序数据库变得特定(但这对您来说可能不是问题)。 this question 的答案可能会提供进一步的帮助。
至于 pq v1.5.2 和 gorm v1.9.12
首先需要判断create method call returns是否出错。像这样
err := GetDB().Create(user).Error
if err != nil {
// code to handle error
}
然后 pq 包有映射到 postgres 服务器错误的特殊类型。它包含可以帮助您识别错误严重性的字段、它的代码、与错误相关的 table 等
psql 字段标识符的完整列表可在此处找到
Error and Notice Message Fields
https://www.postgresql.org/docs/current/protocol-error-fields.html
要解决您的问题,我们可以使用字段
Code
这是错误代码的字符串类型表示。但首先,我们需要转换一个错误并检查类型转换是否成功。像这样
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// code to handle specific error code
}
错误代码列表可以在官方 postgresql 文档中找到 https://www.postgresql.org/docs/9.3/errcodes-appendix.html
并且实际 go pq 特定映射到 github.com/lib/pq/error.go as for pq library
中的错误最后我们可以通过代码处理重复的错误
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// note that type casting here is redundant and used for showing specific
// string type from pq library
if pqErr.Code == pq.ErrorCode("23505") { // 23505 is unique_violation error code for psql
// now you can create error and write it to a message to return it for
// a client
}
}