Kembalikan kesalahan postgres dalam respons api

Dec 24 2020

Saya memiliki dua metode api sederhana dalam kode saya. Metode dengan endpoind /api/user/createmembuat pengguna. Bidang usernameitu 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, userkembalikan 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

1 AlekseySpirin Dec 24 2020 at 17:04

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
    }
}
1 Brits Dec 24 2020 at 02:59

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.