Metamorphosis
Metamorphosis

Reputation: 199

How to handle duplicate unique index error?

I'm using MongoDB. Code to add data to the collection:

  type User struct {
  Firstname        string             `json:"firstname" bson:"firstname"`
  Lastname         *string            `json:"lastname,omitempty" bson:"lastname"`
  Username         string             `json:"username" bson:"username"`
  RegistrationDate primitive.DateTime `json:"registrationDate" bson:"registrationData"`
  LastLogin        primitive.DateTime `json:"lastLogin" bson:"lastLogin"`
}


var client *mongo.Client

func AddUser(response http.ResponseWriter, request *http.Request) {
  collection := client.Database("hattip").Collection("user")
  var user User
  _ = json.NewDecoder(request.Body).Decode(&user)
  insertResult, err := collection.InsertOne(context.TODO(), user)
  if err != nil {
    // here i need to get the kind of error.
    fmt.Println("Error on inserting new user", err)
    response.WriteHeader(http.StatusPreconditionFailed)
  } else {
    fmt.Println(insertResult.InsertedID)
    response.WriteHeader(http.StatusCreated)
  }

}

func main() {
  client = GetClient()
  err := client.Ping(context.Background(), readpref.Primary())
  if err != nil {
    log.Fatal("Couldn't connect to the database", err)
  } else {
    log.Println("Connected!")
  }

  router := mux.NewRouter()
  router.HandleFunc("/person", AddUser).Methods("POST")
  err = http.ListenAndServe("127.0.0.1:8080", router)
  if err == nil {
    fmt.Println("Server is listening...")
  } else {
    fmt.Println(err.Error())
  }

}

func GetClient() *mongo.Client {
  clientOptions := options.Client().ApplyURI("mongodb://127.0.0.1:27017")
  client, err := mongo.NewClient(clientOptions)

  if err != nil {
    log.Fatal(err)
  }
  err = client.Connect(context.Background())
  if err != nil {
    log.Fatal(err)
  }
  return client
}

If I add a record with a username that already exists in the database, I get -

Error on inserting new user multiple write errors: [{write errors: [{E11000 duplicate key error collection: hattip.user index: username_unique dup key: { username: "dd" }}]}, {}]

in the line fmt.Println("Error on inserting new user", err) The record with the string dd in the username field is already there, and the username field is a unique index.

I want to be sure that the error is exact E11000 error (a repeating collection of key errors).

So far i compare err to whole error string that appears on duplication of a unique field, but it's completely wrong. If there is a way to get error code from err object, or there are other ways to solve this problem?

Also, i found mgo package, but to use it properly i have to learn it, rewrite current code and so on, but honestly, it looks good:

if mgo.IsDup(err) {
    err = errors.New("Duplicate name exists")
}

Upvotes: 0

Views: 1484

Answers (2)

tgrk
tgrk

Reputation: 26

The most straightforward option is using the mongo.IsDuplicateKey(error) function here.

Upvotes: 0

Burak Serdar
Burak Serdar

Reputation: 51622

According to the driver docs, InsertOne may return a WriteException, so you can check if the error is a WriteException, and if it is so, then check the WriteErrors in it. Each WriteError contains an error code.

if we, ok:=err.(WriteException); ok {
   for _,e:=range we.WriteErrors {
      // check e.Code
   }
}

You can write an IsDup based on this.

Upvotes: 3

Related Questions