Kembalikan kesalahan postgres dalam respons api
Saya memiliki dua metode api sederhana dalam kode saya. Metode dengan endpoind /api/user/create
membuat pengguna. Bidang username
itu unik. Ketika saya mencoba membuat pengguna dengan nama pengguna yang sama yang sudah ada di database, saya mengalami kesalahan di konsol:
(/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"
Saya ingin menunjukkan kesalahan ini sebagai tanggapan terhadap pengguna, atau entah bagaimana mengidentifikasi jenis kesalahan dalam kode saya, untuk menampilkan pesan kesalahan yang berbeda untuk pengguna. Saya hanya tahu bahwa jika saya mengalami kesalahan, user
kembalikan saya id = 0. Tapi sepertinya bukan pesan yang bagus untuk pengguna.
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
dengan struktur pengguna:
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
}
Jawaban
Sedangkan untuk pq v1.5.2 dan gorm v1.9.12
Pertama, Anda perlu mengidentifikasi apakah panggilan metode membuat mengembalikan kesalahan atau tidak. Seperti itu
err := GetDB().Create(user).Error
if err != nil {
// code to handle error
}
Kemudian paket pq memiliki tipe khusus yang memetakan ke kesalahan server postgres. Ini berisi bidang yang dapat membantu Anda mengidentifikasi tingkat keparahan kesalahan, kodenya, tabel yang terkait dengan kesalahan, dll.
Daftar lengkap pengidentifikasi bidang psql dapat ditemukan di sini di
Error and Notice Message Fields
https://www.postgresql.org/docs/current/protocol-error-fields.html
Untuk mengatasi masalah Anda sebagai opsi, kami dapat menggunakan bidang
Code
Yang merupakan representasi tipe string dari kode kesalahan. Tapi pertama-tama, kita perlu melakukan kesalahan dan memeriksa jenis cetakan berhasil. Seperti itu
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// code to handle specific error code
}
Daftar kode kesalahan dapat ditemukan di dokumen resmi postgresql https://www.postgresql.org/docs/9.3/errcodes-appendix.html
Dan sebenarnya pemetaan khusus go pq untuk kesalahan di github.com/lib/pq/error.go seperti untuk pq library
Dan akhirnya kita bisa menangani kesalahan sebagai duplikat oleh kode
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
}
}
Sesuai komentar, gorm menyediakan akses ke kesalahan database dari fungsi Buat catatan sebagai berikut:
result := GetDB().Create(user)
if result.Error != nil {
// Do something with the error
}
Harap dicatat bahwa memeriksa string kesalahan cenderung membuat database aplikasi Anda spesifik (tetapi ini mungkin tidak menjadi masalah bagi Anda). Jawaban atas pertanyaan ini dapat memberikan bantuan lebih lanjut.