Hi, the team would like user perspective on one of the things we’re working on: error improvements. Currently, writing mgo’s IsDup helper with the driver would look something like this:
func IsDuplicateKeyError(err error) bool { switch e := err.(type) { case mongo.CommandError: return e.Code == 11000 || e.Code == 11001 || e.Code == 12582 || (e.Code == 16460 && strings.Contains(e.Error(), " E11000 ")) case mongo.WriteException: if len(e.WriteErrors) > 0 { for _, we := range e.WriteErrors { if we.Code == 11000 || we.Code == 11001 || we.Code == 12582 || (we.Code == 16460 && strings.Contains(we.Error(), " E11000 ")) { return true } } } case mongo.BulkWriteException: if len(e.WriteErrors) > 0 { for _, we := range e.WriteErrors { if we.Code == 11000 || we.Code == 11001 || we.Code == 12582 || (we.Code == 16460 && strings.Contains(we.Error(), " E11000 ")) { return true } } } default: return false } }
Tentatively, the plan is to add an interface with some helpers that CommandError, WriteException, and BulkWriteException will implement:
type ServerError interface { error HasErrorCode(int) bool HasErrorLabel(string) bool Unwrap() error }
Which would turn that DuplicateKey helper function into this:
func IsDuplicateKeyError(err error) bool {
if e, ok := err.(mongo.ServerError); ok {
return e.HasErrorCode(11000) || e.HasErrorCode(11001) || e.HasErrorCode(12582) ||
(e.HasErrorCode(16460) && strings.Contains(e.Error(), " E11000 "))
}
return false
}
IsDuplicateKeyError would also be one of the standalone helpers added for commonly checked errors:
IsTimeout(error) bool IsDuplicateKeyError(error) bool
ex.
Var err error if mongo.IsTimeout(err) { // handle the error }
Would this solution serve your needs and are there other helpers that would be nice to have?