Trả lại lỗi postgres trong phản hồi api
Tôi có hai phương thức api đơn giản trong mã của mình. Phương thức với endpoind /api/user/createtạo người dùng. Trường usernamelà duy nhất. Khi tôi cố gắng tạo người dùng có cùng tên người dùng đã tồn tại trong cơ sở dữ liệu, tôi gặp lỗi trong bảng điều khiển:
(/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"
Tôi muốn hiển thị lỗi này để phản hồi cho người dùng hoặc bằng cách nào đó xác định loại lỗi trong mã của tôi, để hiển thị các thông báo lỗi khác nhau cho người dùng. Tôi chỉ biết rằng nếu tôi gặp lỗi, hãy usertrả về cho tôi id = 0. Nhưng nó có vẻ không phải là một thông điệp tốt cho người dùng.
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 với cấu trúc người dùng:
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
}
Trả lời
Đối với pq v1.5.2 và gorm v1.9.12
Trước tiên, bạn cần xác định xem liệu cuộc gọi phương thức tạo có trả lại lỗi hay không. Như vậy
err := GetDB().Create(user).Error
if err != nil {
// code to handle error
}
Sau đó, gói pq có loại đặc biệt ánh xạ đến lỗi máy chủ postgres. Nó chứa các trường có thể giúp bạn xác định mức độ nghiêm trọng của lỗi, đó là mã, bảng liên quan đến lỗi, v.v.
Danh sách đầy đủ các định danh trường psql có thể được tìm thấy tại đây trong
Các trường Thông báo Lỗi và Thông báo
https://www.postgresql.org/docs/current/protocol-error-fields.html
Để giải quyết vấn đề của bạn dưới dạng một tùy chọn, chúng tôi có thể sử dụng trường
Code
Đó là một dạng chuỗi biểu diễn mã lỗi. Nhưng trước tiên, chúng ta cần ép kiểu lỗi và kiểm tra kiểu ép thành công. Như vậy
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// code to handle specific error code
}
Danh sách mã lỗi có thể được tìm thấy cả trong tài liệu postgresql chính thức https://www.postgresql.org/docs/9.3/errcodes-appendix.html
Và thực tế ánh xạ pq cụ thể đến lỗi trong github.com/lib/pq/error.go như đối với thư viện pq
Và cuối cùng, chúng tôi có thể xử lý lỗi là trùng lặp theo mã
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
}
}
Theo các nhận xét, gorm cung cấp quyền truy cập vào các lỗi cơ sở dữ liệu từ chức năng Tạo bản ghi như sau:
result := GetDB().Create(user)
if result.Error != nil {
// Do something with the error
}
Xin lưu ý rằng việc kiểm tra chuỗi lỗi có thể làm cho cơ sở dữ liệu ứng dụng của bạn trở nên cụ thể (nhưng đây có thể không phải là vấn đề đối với bạn). Câu trả lời cho câu hỏi này có thể cung cấp hỗ trợ thêm.