Skip to content

Commit

Permalink
Turn off background updates after failures and reduce logging
Browse files Browse the repository at this point in the history
Thunderstore's Sentry logs are full of reports where the background
update fails time and time again. While this is a sort of inverse
survivor bias, it's probably safe to assume that once the background
updates start failing, they're unlikely to start working again. So
turn off the background updates instead.

When the background updates are turned off, an error modal is shown.
I couldn't think of a better way to notify the user about the mod
manager suddenly going "offline". There's a change that making the
background update failure visible to users this way causes a flood
of support requests.

If the failure was due to network error or the request timing out,
the errors are omitted. Currently these two are number 3 and 4 on
Thunderstore's Sentry, and they're just noise since we can't do
~anything about them. Other errors, e.g. related to caching the
package list to IndexedDB are still logged in the hopes that we can
figure out how to solve at least some of them.
  • Loading branch information
anttimaki committed Jun 20, 2024
1 parent be05193 commit 17bdba8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/components/mixins/UtilityMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ import Component from 'vue-class-component';
import R2Error from '../../model/errors/R2Error';
import CdnProvider from '../../providers/generic/connection/CdnProvider';
import ConnectionProvider from '../../providers/generic/connection/ConnectionProvider';
import { isCanceledByRequest, isNetworkError } from '../../utils/HttpUtils';
@Component
export default class UtilityMixin extends Vue {
readonly REFRESH_INTERVAL = 5 * 60 * 1000;
private tsRefreshFailed = false;
private tsRefreshInterval: NodeJS.Timeout|undefined;
hookThunderstoreModListRefresh() {
setInterval(this.tryRefreshThunderstoreModList, this.REFRESH_INTERVAL);
this.tsRefreshInterval = setInterval(
this.tryRefreshThunderstoreModList,
this.REFRESH_INTERVAL
);
}
async refreshThunderstoreModList() {
Expand Down Expand Up @@ -48,8 +53,26 @@ export default class UtilityMixin extends Vue {
await this.refreshThunderstoreModList();
} catch (e) {
if (this.tsRefreshFailed) {
console.error("Two consecutive background refresh attempts failed");
throw e;
// Turn off the background update process after two consecutive
// attempts have failed, as assumably further retries would just
// drain resources and possibly cause other issues with little
// hope of succeeding.
clearInterval(this.tsRefreshInterval);
this.tsRefreshInterval = undefined;
this.$store.commit("error/handleError", new R2Error(
"Background updates halted",
`Two consecutive attempts to update the online mod list on the
background have failed, and the background update has been
disabled. You can continue to use the app, but the online mod
list won't be updated automatically anymore. Error code: "${e}"`,
"Restart the app to reactivate the background update."
));
// Rethrow non-trivial errors to get them logged.
if (!isCanceledByRequest(e) && !isNetworkError(e)) {
throw e;
}
}
this.tsRefreshFailed = true;
Expand Down
6 changes: 6 additions & 0 deletions src/utils/HttpUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ export const makeLongRunningGetRequest = async (
export const isNetworkError = (responseOrError: unknown) =>
responseOrError instanceof Error && responseOrError.message === "Network Error";

/**
* Is the request canceled by the AbortController like the one used by makeLongRunningGetRequest?
*/
export const isCanceledByRequest = (responseOrError: unknown) =>
axios.isCancel(responseOrError);

/**
* Is the Error thrown by Axios request caused by a response timeout?
*/
Expand Down

0 comments on commit 17bdba8

Please sign in to comment.