Skip to content
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

cleanup(reader/handler): calling store.UpdateFeed and store.UpdateFeedError in a defer function #2879

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 33 additions & 36 deletions internal/reader/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,13 @@
}

// RefreshFeed refreshes a feed.
func RefreshFeed(store *storage.Storage, userID, feedID int64, forceRefresh bool) *locale.LocalizedErrorWrapper {
func RefreshFeed(store *storage.Storage, userID, feedID int64, forceRefresh bool) (localizedError *locale.LocalizedErrorWrapper) {
slog.Debug("Begin feed refresh process",
slog.Int64("user_id", userID),
slog.Int64("feed_id", feedID),
slog.Bool("force_refresh", forceRefresh),
)
localizedError = nil

user, storeErr := store.UserByID(userID)
if storeErr != nil {
Expand All @@ -220,7 +221,31 @@
}

originalFeed.CheckedNow()
originalFeed.ScheduleNextCheck(weeklyEntryCount, refreshDelayInMinutes)
// Commit the result to the database at the end of this function.
// If we met an error before entering the defer function, localizedError would not be nil.
defer func() {
originalFeed.ScheduleNextCheck(weeklyEntryCount, refreshDelayInMinutes)
slog.Debug("Updated next check date",
slog.Int64("user_id", userID),
slog.Int64("feed_id", feedID),
slog.Int("weeklyEntryCount", weeklyEntryCount),
slog.Int("retry_delay_in_seconds", retryDelayInSeconds),

Check failure on line 232 in internal/reader/handler/handler.go

View workflow job for this annotation

GitHub Actions / Integration Tests

undefined: retryDelayInSeconds

Check failure on line 232 in internal/reader/handler/handler.go

View workflow job for this annotation

GitHub Actions / Analyze (go)

undefined: retryDelayInSeconds

Check failure on line 232 in internal/reader/handler/handler.go

View workflow job for this annotation

GitHub Actions / Golang Linters

undefined: retryDelayInSeconds

Check failure on line 232 in internal/reader/handler/handler.go

View workflow job for this annotation

GitHub Actions / Unit Tests (ubuntu-latest, 1.23.x)

undefined: retryDelayInSeconds

Check failure on line 232 in internal/reader/handler/handler.go

View workflow job for this annotation

GitHub Actions / Analyze (javascript)

undefined: retryDelayInSeconds

Check failure on line 232 in internal/reader/handler/handler.go

View workflow job for this annotation

GitHub Actions / Unit Tests (macOS-latest, 1.23.x)

undefined: retryDelayInSeconds
slog.Int("refresh_delay_in_minutes", refreshDelayInMinutes),
slog.Time("new_next_check_at", originalFeed.NextCheckAt),
)
if localizedError == nil {
// We have not encountered any error before entering this delay function.
originalFeed.ResetErrorCounter()
if storeErr := store.UpdateFeed(originalFeed); storeErr != nil {
// Update the return value when there is an error.
localizedError = locale.NewLocalizedErrorWrapper(storeErr, "error.database_error", storeErr)
}
}
if localizedError != nil {
originalFeed.WithTranslatedErrorMessage(localizedError.Translate(user.Language))
store.UpdateFeedError(originalFeed)
}
}()

requestBuilder := fetcher.NewRequestBuilder()
requestBuilder.WithUsernameAndPassword(originalFeed.Username, originalFeed.Password)
Expand Down Expand Up @@ -254,17 +279,13 @@
)
}

if localizedError := responseHandler.LocalizedError(); localizedError != nil {
if localizedError = responseHandler.LocalizedError(); localizedError != nil {
slog.Warn("Unable to fetch feed", slog.String("feed_url", originalFeed.FeedURL), slog.Any("error", localizedError.Error()))
originalFeed.WithTranslatedErrorMessage(localizedError.Translate(user.Language))
store.UpdateFeedError(originalFeed)
return localizedError
}

if store.AnotherFeedURLExists(userID, originalFeed.ID, responseHandler.EffectiveURL()) {
localizedError := locale.NewLocalizedErrorWrapper(ErrDuplicatedFeed, "error.duplicated_feed")
originalFeed.WithTranslatedErrorMessage(localizedError.Translate(user.Language))
store.UpdateFeedError(originalFeed)
localizedError = locale.NewLocalizedErrorWrapper(ErrDuplicatedFeed, "error.duplicated_feed")
return localizedError
}

Expand All @@ -284,40 +305,25 @@

updatedFeed, parseErr := parser.ParseFeed(responseHandler.EffectiveURL(), bytes.NewReader(responseBody))
if parseErr != nil {
localizedError := locale.NewLocalizedErrorWrapper(parseErr, "error.unable_to_parse_feed", parseErr)

if errors.Is(parseErr, parser.ErrFeedFormatNotDetected) {
localizedError = locale.NewLocalizedErrorWrapper(parseErr, "error.feed_format_not_detected", parseErr)
} else {
localizedError = locale.NewLocalizedErrorWrapper(parseErr, "error.unable_to_parse_feed", parseErr)
}

originalFeed.WithTranslatedErrorMessage(localizedError.Translate(user.Language))
store.UpdateFeedError(originalFeed)
return localizedError
}

// If the feed has a TTL defined, we use it to make sure we don't check it too often.
refreshDelayInMinutes = updatedFeed.TTL

// Set the next check at with updated arguments.
originalFeed.ScheduleNextCheck(weeklyEntryCount, refreshDelayInMinutes)

slog.Debug("Updated next check date",
slog.Int64("user_id", userID),
slog.Int64("feed_id", feedID),
slog.Int("refresh_delay_in_minutes", refreshDelayInMinutes),
slog.Time("new_next_check_at", originalFeed.NextCheckAt),
)

originalFeed.Entries = updatedFeed.Entries
processor.ProcessFeedEntries(store, originalFeed, user, forceRefresh)

// We don't update existing entries when the crawler is enabled (we crawl only inexisting entries). Unless it is forced to refresh
updateExistingEntries := forceRefresh || !originalFeed.Crawler
newEntries, storeErr := store.RefreshFeedEntries(originalFeed.UserID, originalFeed.ID, originalFeed.Entries, updateExistingEntries)
if storeErr != nil {
localizedError := locale.NewLocalizedErrorWrapper(storeErr, "error.database_error", storeErr)
originalFeed.WithTranslatedErrorMessage(localizedError.Translate(user.Language))
store.UpdateFeedError(originalFeed)
localizedError = locale.NewLocalizedErrorWrapper(storeErr, "error.database_error", storeErr)
return localizedError
}

Expand Down Expand Up @@ -354,14 +360,5 @@
}
}

originalFeed.ResetErrorCounter()

if storeErr := store.UpdateFeed(originalFeed); storeErr != nil {
localizedError := locale.NewLocalizedErrorWrapper(storeErr, "error.database_error", storeErr)
originalFeed.WithTranslatedErrorMessage(localizedError.Translate(user.Language))
store.UpdateFeedError(originalFeed)
return localizedError
}

return nil
return localizedError
}
Loading