वापसी एपीआई प्रतिक्रिया में त्रुटियों को स्थगित कर देती है

Dec 24 2020

मेरे पास अपने कोड में दो सरल एपी विधियां हैं। एंडपाइंड के साथ विधि /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है तो मुझे आईडी = 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
}

जवाब

1 AlekseySpirin Dec 24 2020 at 17:04

Pq v1.5.2 और gorm v1.9.12 के रूप में

सबसे पहले, आपको यह पहचानने की आवश्यकता है कि क्या विधि कॉल रिटर्न बनाता है या नहीं। इस तरह

err := GetDB().Create(user).Error
if err != nil {
    // code to handle error
}

तब pq पैकेज में विशेष प्रकार होता है जो सर्वर त्रुटि को पोस्ट करने के लिए मैप करता है। इसमें फ़ील्ड शामिल हैं जो आपको त्रुटि गंभीरता की पहचान करने में मदद कर सकते हैं, यह कोड, तालिका जो त्रुटि से संबंधित है आदि।

Psql फ़ील्ड पहचानकर्ताओं की पूरी सूची यहां पाई जा सकती है

त्रुटि और सूचना संदेश फ़ील्ड

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
}

त्रुटि कोड की सूची आधिकारिक पोस्टग्रैस्कल डॉक्स दोनों में पाई जा सकती है https://www.postgresql.org/docs/9.3/errcodes-appendix.html

और वास्तविक gq gqub.com/lib/pq/error.go में त्रुटि के लिए pq विशिष्ट मैपिंग को pq लाइब्रेरी के रूप में देखें

और अंत में हम कोड द्वारा डुप्लिकेट के रूप में त्रुटि को संभाल सकते हैं

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

टिप्पणियों के अनुसार gorm इस प्रकार से रिकॉर्ड बनाने के कार्य से डेटाबेस त्रुटियों तक पहुँच प्रदान करता है:

result := GetDB().Create(user)
if result.Error != nil {
   // Do something with the error
}

कृपया ध्यान दें कि त्रुटि स्ट्रिंग की जांच करने से आपके एप्लिकेशन डेटाबेस को विशिष्ट बनाने की संभावना है (लेकिन यह आपके लिए कोई समस्या नहीं हो सकती है)। इस प्रश्न के उत्तर आगे सहायता प्रदान कर सकते हैं।