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
|
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 returns a token or an error.
|
||||||
// Token must be safe for concurrent use by multiple goroutines.
|
// Token must be safe for concurrent use by multiple goroutines.
|
||||||
// The returned Token must not be modified.
|
// The returned Token must not be modified.
|
||||||
|
@ -242,11 +273,15 @@ func (ts *TokenSource) Token() (*oauth2.Token, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
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)
|
fs.Debugf(ts.name, "Token refresh failed try %d/%d: %v", i, maxTries, err)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
if err != nil {
|
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)
|
changed = changed || (*token != *ts.token)
|
||||||
ts.token = token
|
ts.token = token
|
||||||
|
|
Loading…
Reference in a new issue