Skip to content
Open
Show file tree
Hide file tree
Changes from all 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