forked from TrueCloudLab/rclone
parent
02d6d28ec4
commit
d66f5e8db0
1 changed files with 36 additions and 1 deletions
|
@ -204,6 +204,37 @@ func (ts *TokenSource) reReadToken() (changed bool) {
|
|||
return changed
|
||||
}
|
||||
|
||||
type retrieveErrResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// If err is nil or an error other than fatal OAuth errors, returns err itself.
|
||||
// Otherwise returns a more user-friendly error.
|
||||
func maybeWrapOAuthError(err error, remoteName string) (newErr error) {
|
||||
newErr = err
|
||||
if rErr, ok := err.(*oauth2.RetrieveError); ok {
|
||||
if rErr.Response.StatusCode == 400 || rErr.Response.StatusCode == 401 {
|
||||
fs.Debugf(remoteName, "got fatal oauth error: %v", rErr)
|
||||
var resp retrieveErrResponse
|
||||
if err = json.Unmarshal(rErr.Body, &resp); err != nil {
|
||||
newErr = fmt.Errorf("(can't decode error info) - try refreshing token with \"rclone config reconnect %s:\"", remoteName)
|
||||
return
|
||||
}
|
||||
var suggestion string
|
||||
switch resp.Error {
|
||||
case "invalid_client", "unauthorized_client", "unsupported_grant_type", "invalid_scope":
|
||||
suggestion = fmt.Sprintf("if you're using your own client id/secret, make sure they're properly set up following the docs")
|
||||
case "invalid_grant":
|
||||
fallthrough
|
||||
default:
|
||||
suggestion = fmt.Sprintf("maybe token expired? - try refreshing with \"rclone config reconnect %s:\"", remoteName)
|
||||
}
|
||||
newErr = fmt.Errorf("%s: %s", resp.Error, suggestion)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Token returns a token or an error.
|
||||
// Token must be safe for concurrent use by multiple goroutines.
|
||||
// The returned Token must not be modified.
|
||||
|
@ -242,11 +273,15 @@ func (ts *TokenSource) Token() (*oauth2.Token, error) {
|
|||
if err == nil {
|
||||
break
|
||||
}
|
||||
if newErr := maybeWrapOAuthError(err, ts.name); newErr != err {
|
||||
err = newErr // Fatal OAuth error
|
||||
break
|
||||
}
|
||||
fs.Debugf(ts.name, "Token refresh failed try %d/%d: %v", i, maxTries, err)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't fetch token - maybe it has expired? - refresh with \"rclone config reconnect %s:\": %w", ts.name, err)
|
||||
return nil, fmt.Errorf("couldn't fetch token: %w", err)
|
||||
}
|
||||
changed = changed || (*token != *ts.token)
|
||||
ts.token = token
|
||||
|
|
Loading…
Reference in a new issue