/
githubmirror
/
rclone
Обзор
Документация
Войти
/
githubmirror
/
rclone
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
backend/putio/error.go
69 строк
2 KB
Nick Craig-Wood
putio: fix sync deletions failing with 400 TRASH_LOCK_TIMEOUT errors
17 июл 2026, 20:29
17 июл 2026, 20:29
74d376a
Код
Авторство
О чём код?
package putio import ( "context" "fmt" "net/http" "slices" "strconv" "time" "github.com/putdotio/go-putio/putio" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/lib/pacer" ) func checkStatusCode(resp *http.Response, expected ...int) error { if slices.Contains(expected, resp.StatusCode) { return nil } return &statusCodeError{response: resp} } type statusCodeError struct { response *http.Response } func (e *statusCodeError) Error() string { return fmt.Sprintf("unexpected status code (%d) response while doing %s to %s", e.response.StatusCode, e.response.Request.Method, e.response.Request.URL.String()) } // This method is called from fserrors.ShouldRetry() to determine if an error should be retried. // Some errors (e.g. 429 Too Many Requests) are handled before this step, so they are not included here. func (e *statusCodeError) Temporary() bool { return e.response.StatusCode >= 500 } // shouldRetry returns a boolean as to whether this err deserves to be // retried. It returns the err as a convenience func shouldRetry(ctx context.Context, err error) (bool, error) { if fserrors.ContextError(ctx, &err) { return false, err } if err == nil { return false, nil } if perr, ok := err.(*putio.ErrorResponse); ok { // put.io serializes trash operations per account, so // concurrent deletes can fail with a 400 // TRASH_LOCK_TIMEOUT error which deserves a retry. if perr.Type == "TRASH_LOCK_TIMEOUT" { return true, err } err = &statusCodeError{response: perr.Response} } if scerr, ok := err.(*statusCodeError); ok && scerr.response.StatusCode == 429 { delay := defaultRateLimitSleep header := scerr.response.Header.Get("x-ratelimit-reset") if header != "" { if resetTime, cerr := strconv.ParseInt(header, 10, 64); cerr == nil { delay = time.Until(time.Unix(resetTime+1, 0)) } } return true, pacer.RetryAfterError(scerr, delay) } if fserrors.ShouldRetry(err) { return true, err } return false, err }