Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

How should we be checking for errors in mongo-go-driver?

In AWS SDK, they have AWS specific errors that are defined as consts that you can check against, e.g.

	if err != nil {
		if aerr, ok := err.(awserr.Error); ok {
			// If it's an AWS error, override the dumb message to a human readable one
			switch aerr.Code() {
			case secretsmanager.ErrCodeDecryptionFailure:
				err = fmt.Errorf("Secrets Manager can't decrypt the protected secret text using the provided KMS key")
			case secretsmanager.ErrCodeInternalServiceError:
				err = fmt.Errorf("An error occurred on the server side")
			case secretsmanager.ErrCodeInvalidParameterException:
				err = fmt.Errorf("You provided an invalid value for a parameter")
			case secretsmanager.ErrCodeInvalidRequestException:
				err = fmt.Errorf("You provided a parameter value that is not valid for the current state of the resource")
			case secretsmanager.ErrCodeResourceNotFoundException:
				err = fmt.Errorf("The secret was not found or we don't have permission to view it")
			}
		}
	}

Is there something similar to do for mongo? Are you guys using some kind of wrapped errors? How I’m having to do error checking presently involves a strings.Contains, e.g.

	errStr := err.Error()
	switch {
	case strings.HasPrefix(errStr, "(IndexKeySpecsConflict) Index must have unique name."):
	case strings.HasPrefix(errStr, "(DuplicateKey)"):
		// We can ignore conflicts
		// log.WithFields(logrus.Fields{
		// 	"index":       m.Key,
		// 	"collection":  coll.Name(),
		// 	"database":    coll.Database().Name(),
		// 	"conflictErr": err,
		// }).Debug("Index was previously created - this is an Ensure function, so this is fine")
		err = nil
	case strings.HasPrefix(errStr, "(DatabaseDifferCase)"):
		// The casing is different on the DB - we need to error out
		log.WithFields(logrus.Fields{
			"index":      m.Key,
			"collection": coll.Name(),
			"database":   coll.Database().Name(),
			"err":        err,
		}).Errorf("Failed to create index because a DB with the same name exists with a different case")
	default:
		log.WithFields(logrus.Fields{
			"index":      m.Key,
			"collection": coll.Name(),
			"database":   coll.Database().Name(),
			"err":        err,
		}).Errorf("Failed to create index")
	}

Is there a better/recommended method for checking for errors in general in mongo?

Hi @TopherGopher,

Looks like all of these are server errors, so they should all be of type mongo.CommandError. The trickiest one is DuplicateKey because the format of that error has changed over server versions. For example, it might be returned as a write error from the server, in which case it’d be a mongo.WriteException or mongo.BulkWriteException, depending on the method you use (all writes return a WriteException except for InsertMany and BulkWrite).

The DuplicateKey case is definitely confusing. There’s an open GODRIVER ticket to implement something like mgo’s IsDup function to handle all of that logic: https://jira.mongodb.org/browse/GODRIVER-972.

– Divjot

2 Likes