-
Notifications
You must be signed in to change notification settings - Fork 913
GODRIVER-1992 Implement ServerErrors interface for driver errors #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -202,13 +202,14 @@ type ServerError interface { | |
HasErrorMessage(string) bool | ||
// HasErrorCodeWithMessage returns true if any of the contained errors have the specified code and message. | ||
HasErrorCodeWithMessage(int, string) bool | ||
|
||
serverError() | ||
} | ||
|
||
var _ ServerError = CommandError{} | ||
var _ ServerError = WriteException{} | ||
var _ ServerError = BulkWriteException{} | ||
var _ ServerError = driver.WriteCommandError{} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would returning a IIUC, |
||
var _ ServerError = driver.WriteConcernError{} | ||
var _ ServerError = driver.Error{} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue that spurred this ticket was a deeply wrapped Would a preferable alternative be to have the error translation functions translate wrapped errors as well? E.g. have @iwysiu would the fix of GODRIVER-1991 solve this problem entirely? If no errors are returned in |
||
|
||
// CommandError represents a server error during execution of a command. This can be returned by any operation. | ||
type CommandError struct { | ||
|
@@ -264,9 +265,6 @@ func (e CommandError) IsMaxTimeMSExpiredError() bool { | |
return e.Code == 50 || e.Name == "MaxTimeMSExpired" | ||
} | ||
|
||
// serverError implements the ServerError interface. | ||
func (e CommandError) serverError() {} | ||
|
||
// WriteError is an error that occurred during execution of a write operation. This error type is only returned as part | ||
// of a WriteException or BulkWriteException. | ||
type WriteError struct { | ||
|
@@ -395,9 +393,6 @@ func (mwe WriteException) HasErrorCodeWithMessage(code int, message string) bool | |
return false | ||
} | ||
|
||
// serverError implements the ServerError interface. | ||
func (mwe WriteException) serverError() {} | ||
|
||
func convertDriverWriteConcernError(wce *driver.WriteConcernError) *WriteConcernError { | ||
if wce == nil { | ||
return nil | ||
|
@@ -498,9 +493,6 @@ func (bwe BulkWriteException) HasErrorCodeWithMessage(code int, message string) | |
return false | ||
} | ||
|
||
// serverError implements the ServerError interface. | ||
func (bwe BulkWriteException) serverError() {} | ||
|
||
// returnResult is used to determine if a function calling processWriteError should return | ||
// the result or return nil. Since the processWriteError function is used by many different | ||
// methods, both *One and *Many, we need a way to differentiate if the method should return | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementing
ServerError
for types outside of themongo
package (in this case indriver
) means that I must remove this guard. WithoutserverError()
, users can now implement theServerError
interface for their own types. We do document that this is discouraged, but if there's some way I'm missing to keep this guard in, let me know 🌺There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't necessarily think its better, but we could alternatively have a drivers.ServerError interface that has the same functions and have the helpers that check for the ServerError interface also check for the drivers.ServerError interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I don't love the repetition, but it might be better than removing the guard altogether. Any thoughts @kevinAlbs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iwysiu does copying the interface take away from the usability?
I thought the motivation of the
ServerError
interface was to be a convenient interface to inspect all server errors.A distinct
driver.ServerError
would be less accessible if it is in thex
package, and it would require the user to check for both interfaces.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would make it more annoying for end users. If we're not worried about users implementing it, i think removing the guard is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not too familiar with the nuances of whether this should be a sealed interface.
No functions take a
ServerError
as a direct argument. The helperIsDuplicateKeyError
could accept an error that the user has defined which implementsServerError
. But that seems harmless to me.Are there other risks?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's much risk to "unsealing" the
ServerError
interface. As @kevinAlbs mentioned, nothing uses it as an argument directly, and even if someone implemented the interface, they wouldn't get any unexpected behavior, it just doesn't make much sense to do so.Alternately, there's actually no reason thatServerError
needs to be exported. We could leaveServerError
as is, define a new unexported interface likeserverError
with the same function signatures, add a note toServerError
that it's unused and only there to maintain public API compatibility.Edit:
My understanding is that a common use case is for users to type-assert an error is
mongo.ServerError
so they can access functions likeHasErrorCode()
andHasErrorLabel()
.E.g.
In that case, creating a new unexported
serverError
that is implemented by errors returned by packages inx
would not satisfy an expected use case ofServerError
.