-
Notifications
You must be signed in to change notification settings - Fork 3
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
Don't retry SSH connection when auth fails #818
Conversation
Authentication failures can not be resolved by retrying the connection with the same credentials.
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.
LGTM, only one minor suggestion.
internal/sftp/client.go
Outdated
type AuthError struct { | ||
err error | ||
} | ||
|
||
func (e *AuthError) Error() string { | ||
return e.err.Error() | ||
} | ||
|
||
func (e *AuthError) Unwrap() error { | ||
return e.err | ||
} | ||
|
||
func NewAuthError(e error) *AuthError { | ||
return &AuthError{err: e} | ||
} |
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.
A possible alternative:
type AuthError struct {
Reason string
}
func (e *AuthError) Error() string {
return fmt.Sprintf("auth: %s", e.Reason)
}
func NewAuthError(err error) error {
return &AuthError{Reason: err.Error()}
}
This version:
- Doesn't use Unwrap because we don't need to give access to the underlying error.
- Uses the error type in the constructor signature, see https://go.dev/doc/faq#nil_error:
It's a good idea for functions that return errors always to use the error type in their signature rather than a concrete type such as *MyError, to help guarantee the error is created correctly. As an example, os.Open returns an error even though, if not nil, it's always of concrete type *os.PathError.
I think that we'd want the function to return a concrete type (*AuthError) if we were doing some performance-focused work, e.g. https://github.com/connectrpc/connect-go/blob/d88758dc0e89170db922ecd20f16cec57662ec23/error.go#L117-L128 could be a good example where the design was driven by performance objectives, like avoiding memory allocations. This is a guess though, not entirely sure.
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.
@sevein does Reason
need to be exported?
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.
Exporting the Reason
field does have the nice benefit of being able to set an arbitrary string without having to create an error first, e.g.
e := &sftp.AuthError{Reason: "bad password"}
vs.
e := sftp.NewAuthError(errors.New("bad password"))
a4db585
to
fdb128b
Compare
@@ -17,32 +18,32 @@ import ( | |||
// returns a client connection. | |||
// | |||
// Only private key authentication is currently supported, with or without a | |||
// passphrase. | |||
// passphrase.SSH: %v", |
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.
Looks like this was accidentally changed!
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.
Oops! 🤦
Authentication failures can not be resolved by retrying the connection with the same credentials.