Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion internal/integration/clam_prose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ func clamMultiByteTruncLogs(mt *mtest.T) []truncValidator {

// Insert started.
validators[0] = newTruncValidator(mt, cmd, func(cmd string) error {

// Remove the suffix from the command string.
cmd = cmd[:len(cmd)-len(logger.TruncationSuffix)]

Expand Down
30 changes: 26 additions & 4 deletions mongo/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ type LabeledError interface {
HasErrorLabel(string) bool
}

type errorCoder interface {
ErrorCodes() []int
}

var _ errorCoder = ServerError(nil)

// ServerError is the interface implemented by errors returned from the server. Custom implementations of this
// interface should not be used in production.
type ServerError interface {
Expand Down Expand Up @@ -364,10 +370,12 @@ func hasErrorCode(srvErr ServerError, code int) bool {
return false
}

var _ ServerError = CommandError{}
var _ ServerError = WriteError{}
var _ ServerError = WriteException{}
var _ ServerError = BulkWriteException{}
var (
_ ServerError = CommandError{}
_ ServerError = WriteError{}
_ ServerError = WriteException{}
_ ServerError = BulkWriteException{}
)
Comment on lines +373 to +378
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to define interface{ ErrorCodes() []int } here and add additional checks that these structs also satisfies the interface? It may prevent ErrorCodes() in ServerError from being modified.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, will update


var _ error = ClientBulkWriteException{}

Expand Down Expand Up @@ -901,3 +909,17 @@ func joinBatchErrors(errs []error) string {

return buf.String()
}

// ErrorCodes returns the list of server error codes contained in err.
func ErrorCodes(err error) []int {
if err == nil {
return nil
}

var ec errorCoder
if errors.As(wrapErrors(err), &ec) {
return ec.ErrorCodes()
}

return []int{}
}
76 changes: 76 additions & 0 deletions mongo/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,3 +760,79 @@ func (n netErr) Temporary() bool {
}

var _ net.Error = (*netErr)(nil)

func TestErrorCodes(t *testing.T) {
tests := []struct {
name string
input error
want []int
}{
{
name: "nil error",
input: nil,
want: nil,
},
{
name: "non-server error",
input: errors.New("boom"),
want: []int{},
},
{
name: "CommandError single code",
input: CommandError{Code: 123},
want: []int{123},
},
{
name: "WriteError single code",
input: WriteError{Code: 45},
want: []int{45},
},
{
name: "WriteException write errors only",
input: WriteException{WriteErrors: WriteErrors{{Code: 1}, {Code: 2}}},
want: []int{1, 2},
},
{
name: "WriteException with write concern error",
input: WriteException{WriteErrors: WriteErrors{{Code: 1}}, WriteConcernError: &WriteConcernError{Code: 64}},
want: []int{1, 64},
},
{
name: "BulkWriteException write errors only",
input: BulkWriteException{
WriteErrors: []BulkWriteError{
{WriteError: WriteError{Code: 10}},
{WriteError: WriteError{Code: 11}},
},
},
want: []int{10, 11},
},
{
name: "BulkWriteException with write concern error",
input: BulkWriteException{
WriteErrors: []BulkWriteError{
{WriteError: WriteError{Code: 10}},
{WriteError: WriteError{Code: 11}},
},
WriteConcernError: &WriteConcernError{Code: 79},
},
want: []int{10, 11, 79},
},
{
name: "driver.Error wraps to CommandError",
input: driver.Error{Code: 91, Message: "shutdown in progress"},
want: []int{91},
},
{
name: "wrapped driver.Error",
input: fmt.Errorf("context: %w", driver.Error{Code: 262, Message: "ExceededTimeLimit"}),
want: []int{262},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, ErrorCodes(tt.input))
})
}
}
1 change: 0 additions & 1 deletion x/mongo/driver/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,6 @@ func (op Operation) Execute(ctx context.Context) error {
var moreToCome bool
var startedInfo startedInformation
*wm, moreToCome, startedInfo, err = op.createWireMessage(ctx, maxTimeMS, (*wm)[:0], desc, conn, requestID)

if err != nil {
return err
}
Expand Down
Loading