From a5d6da7373dc324c504810df2e64abdb6e5c6459 Mon Sep 17 00:00:00 2001 From: soup Date: Sat, 6 May 2023 18:22:08 +0200 Subject: [PATCH] feat(releases): improve error handling on torrent download (#880) * feat/check-content-type-torrent-download * check for text/html instead * check for status codes above 308 * refactor * make sure < 499 goes to content-type check * fix content header check by accounting for charset * retry on 404 * change to errors.New for 404 * make use of verbs * handle http errors as cases * check contentType with strings.Contains instead * adjust message for unauthorized and forbidden --------- Co-authored-by: ze0s <43699394+zze0s@users.noreply.github.com> --- internal/domain/release.go | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/internal/domain/release.go b/internal/domain/release.go index f5de9a2..1f5b63b 100644 --- a/internal/domain/release.go +++ b/internal/domain/release.go @@ -395,14 +395,35 @@ func (r *Release) downloadTorrentFile(ctx context.Context) error { } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - unRecoverableErr := errors.Wrap(ErrUnrecoverableError, "unrecoverable error downloading torrent (%v) file (%v) from '%v' - status code: %d", r.TorrentName, r.TorrentURL, r.Indexer, resp.StatusCode) + // Check server response + switch resp.StatusCode { + case http.StatusOK: + // Continue processing the response + case http.StatusMovedPermanently, http.StatusFound, http.StatusSeeOther, http.StatusTemporaryRedirect, http.StatusPermanentRedirect: + // Handle redirect + return retry.Unrecoverable(errors.New("redirect encountered for torrent (%v) file (%v) from '%v' - status code: %d. Check indexer keys.", r.TorrentName, r.TorrentURL, r.Indexer, resp.StatusCode)) - if resp.StatusCode == 401 || resp.StatusCode == 403 || resp.StatusCode == 404 || resp.StatusCode == 405 { - return retry.Unrecoverable(unRecoverableErr) - } + case http.StatusUnauthorized, http.StatusForbidden: + return retry.Unrecoverable(errors.New("unrecoverable error downloading torrent (%v) file (%v) from '%v' - status code: %d. Check indexer keys", r.TorrentName, r.TorrentURL, r.Indexer, resp.StatusCode)) - return errors.New("unexpected status: %v", resp.StatusCode) + case http.StatusMethodNotAllowed: + return retry.Unrecoverable(errors.New("unrecoverable error downloading torrent (%v) file (%v) from '%v' - status code: %d. Check if the request method is correct", r.TorrentName, r.TorrentURL, r.Indexer, resp.StatusCode)) + + case http.StatusNotFound: + return errors.New("torrent %s not found on %s (%d) - retrying", r.TorrentName, r.Indexer, resp.StatusCode) + + case http.StatusInternalServerError, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout: + return errors.New("server error (%d) encountered while downloading torrent (%v) file (%v) from '%v' - retrying", resp.StatusCode, r.TorrentName, r.TorrentURL, r.Indexer) + + default: + return retry.Unrecoverable(errors.New("unexpected status code %d: check indexer keys for %s", resp.StatusCode, r.Indexer)) + } + + // Check if the Content-Type header is correct + contentType := resp.Header.Get("Content-Type") + + if strings.Contains(contentType, "text/html") { + return retry.Unrecoverable(errors.New("unexpected content type '%s': check indexer keys for %s", contentType, r.Indexer)) } resetTmpFile := func() {