Skip to content
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

Improve errors #28

Merged
merged 6 commits into from
Oct 11, 2018
Merged
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
10 changes: 5 additions & 5 deletions neo4j/config_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type ServerAddress interface {
// resolve the initial address used to create the driver.
type ServerAddressResolver func(address ServerAddress) []ServerAddress

func newServerAddressUrl(hostname string, port string) *url.URL {
func newServerAddressURL(hostname string, port string) *url.URL {
if hostname == "" {
return nil
}
Expand All @@ -51,12 +51,12 @@ func newServerAddressUrl(hostname string, port string) *url.URL {
return &url.URL{Host: hostAndPort}
}

// A helper function that generates a ServerAddress with provided hostname and port information.
// NewServerAddress generates a ServerAddress with provided hostname and port information.
func NewServerAddress(hostname string, port string) ServerAddress {
return newServerAddressUrl(hostname, port)
return newServerAddressURL(hostname, port)
}

func wrapAddressResolverOrNil(addressResolver ServerAddressResolver) gobolt.UrlAddressResolver {
func wrapAddressResolverOrNil(addressResolver ServerAddressResolver) gobolt.URLAddressResolver {
if addressResolver == nil {
return nil
}
Expand All @@ -65,7 +65,7 @@ func wrapAddressResolverOrNil(addressResolver ServerAddressResolver) gobolt.UrlA
var result []*url.URL

for _, address := range addressResolver(address) {
result = append(result, newServerAddressUrl(address.Hostname(), address.Port()))
result = append(result, newServerAddressURL(address.Hostname(), address.Port()))
}

return result
Expand Down
127 changes: 119 additions & 8 deletions neo4j/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,142 @@ import (
"github.com/neo4j-drivers/gobolt"
)

type databaseError struct {
classification string
code string
message string
}

type connectorError struct {
state int
code int
description string
}

type driverError struct {
message string
}

func newDriverError(format string, args ...interface{}) error {
type sessionExpiredError struct {
message string
}

func (failure *databaseError) BoltError() bool {
return true
}

func (failure *databaseError) Classification() string {
return failure.classification
}

func (failure *databaseError) Code() string {
return failure.code
}

func (failure *databaseError) Message() string {
return failure.message
}

func (failure *databaseError) Error() string {
return fmt.Sprintf("database returned error [%s]: %s", failure.code, failure.message)
}

func (failure *connectorError) BoltError() bool {
return true
}

func (failure *connectorError) State() int {
return failure.state
}

func (failure *connectorError) Code() int {
return failure.code
}

func (failure *connectorError) Description() string {
return failure.description
}

func (failure *connectorError) Error() string {
return fmt.Sprintf("expected connection to be in READY state, where it is %d [error is %d]", failure.state, failure.code)
}

func (failure *driverError) BoltError() bool {
return true
}

func (failure *driverError) Message() string {
return failure.message
}

func (failure *driverError) Error() string {
return failure.message
}

func (failure *sessionExpiredError) BoltError() bool {
return true
}

func (failure *sessionExpiredError) Error() string {
return failure.message
}

func newDriverError(format string, args ...interface{}) gobolt.GenericError {
return &driverError{message: fmt.Sprintf(format, args...)}
}

func newSessionExpiredError(format string, args ...interface{}) error {
return &sessionExpiredError{message: fmt.Sprintf(format, args...)}
}

func newDatabaseError(classification, code, message string) gobolt.DatabaseError {
return &databaseError{code: code, message: message, classification: classification}
}

func newConnectorError(state int, code int, description string) gobolt.ConnectorError {
return &connectorError{state: state, code: code, description: description}
}

func isRetriableError(err error) bool {
return gobolt.IsServiceUnavailable(err) || gobolt.IsTransientError(err) || gobolt.IsWriteError(err)
}

func (err *driverError) Error() string {
return err.message
// IsSecurityError is a utility method to check if the provided error is related with any
// TLS failure or authentication issues.
func IsSecurityError(err error) bool {
return gobolt.IsSecurityError(err)
}

func IsServiceUnavailable(err error) bool {
return gobolt.IsServiceUnavailable(err)
// IsAuthenticationError is a utility method to check if the provided error is related with any
// authentication issues.
func IsAuthenticationError(err error) bool {
return gobolt.IsAuthenticationError(err)
}

func IsDriverError(err error) bool {
_, ok := err.(*driverError)
return ok
// IsClientError is a utility method to check if the provided error is related with the client
// carrying out an invalid operation.
func IsClientError(err error) bool {
return gobolt.IsClientError(err)
}

// IsTransientError is a utility method to check if the provided error is related with a temporary
// failure that may be worked around by retrying.
func IsTransientError(err error) bool {
return gobolt.IsTransientError(err)
}

// IsSessionExpired is a utility method to check if the session no longer satisfy the criteria
// under which it was acquired, e.g. a server no longer accepts write requests.
func IsSessionExpired(err error) bool {
if _, ok := err.(*sessionExpiredError); ok {
return true
}

return gobolt.IsSessionExpired(err)
}

// IsServiceUnavailable is a utility method to check if the provided error can be classified
// to be in service unavailable category.
func IsServiceUnavailable(err error) bool {
return gobolt.IsServiceUnavailable(err)
}
Loading