Skip to content
Open
Show file tree
Hide file tree
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
21 changes: 14 additions & 7 deletions src/components/modals/ErrorModal.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<script lang="ts" setup>
import R2Error from '../../model/errors/R2Error';
import CdnProvider from '../../providers/generic/connection/CdnProvider';
import { getStore } from '../../providers/generic/store/StoreProvider';
import { State } from '../../store';
import { computed, ComputedRef } from 'vue';
import { computed } from 'vue';

const store = getStore<State>();

const error: ComputedRef<R2Error | null> = computed(() => store.state.error.error);
const error = computed(() => store.state.error.error);
const currentCdnName = computed(() => CdnProvider.current.label);

const name = computed(() => error.value ? error.value.name : '');
const message = computed(() => error.value ? error.value.message : '');
const solution = computed(() => error.value ? error.value.solution : '');
const showCurrentCdn = computed(() => error.value ? error.value.showCurrentCdn : false);

function close() {
store.commit('error/discardError');
Expand All @@ -26,11 +29,15 @@ function close() {
<p>{{message}}</p>
<div v-if="solution">
<h5 class="title is-5">Suggestion</h5>
<p>{{solution}}</p>
<p>{{solution + (showCurrentCdn ? ` Current CDN: ${currentCdnName}` : '')}}</p>
</div>
<div class="mt-3 text-right" v-if="error.action">
<button class="button is-white" @click="() => { error.action.function(); close(); }">
{{error.action.label}}
<div class="mt-3 text-right" v-if="error.actions">
<button
v-for="action in error.actions"
class="button is-white ml-3"
@click="action.function(); if(action.closeModal) close()"
>
{{action.label}}
</button>
</div>
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/components/profiles-modals/ImportProfileModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ThunderstoreCombo from "../../model/ThunderstoreCombo";
import InteractionProvider from "../../providers/ror2/system/InteractionProvider";
import { ProfileImportExport } from "../../r2mm/mods/ProfileImportExport";
import { sleep } from "../../utils/Common";
import { addSolutionsToError } from "../../utils/DownloadUtils";
import * as ProfileUtils from "../../utils/ProfileUtils";
import { ModalCard } from "../all";
import OnlineModList from "../views/OnlineModList.vue";
Expand Down Expand Up @@ -106,6 +107,7 @@ async function onProfileCodeEntered() {
await validateProfileFile([filepath]);
} catch (e: any) {
const err = R2Error.fromThrownValue(e, 'Failed to import profile');
addSolutionsToError(err);
store.commit('error/handleError', err);
} finally {
importViaCodeInProgress.value = false;
Expand Down Expand Up @@ -242,7 +244,9 @@ async function importProfile(targetProfileName: string, mods: ExportMod[], zipPa
} catch (e) {
await store.dispatch('profiles/ensureProfileExists');
closeModal();
store.commit('error/handleError', R2Error.fromThrownValue(e));
const r2Error = R2Error.fromThrownValue(e);
addSolutionsToError(r2Error);
store.commit('error/handleError', r2Error);
return;
}

Expand Down
7 changes: 4 additions & 3 deletions src/model/errors/R2Error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default class R2Error extends Error {
public stack?: string | undefined;
public solution: string;
public errorReferenceString: string | undefined;
public action?: Action;
public actions: Action[] = [];
public showCurrentCdn: boolean = false;

public constructor(name: string, message: string, solution: string | null = null) {
super(message);
Expand All @@ -33,8 +34,8 @@ export default class R2Error extends Error {
}
}

public setAction(action: Action) {
this.action = action;
public addAction(action: Action) {
this.actions.push(action);
}
}

Expand Down
22 changes: 12 additions & 10 deletions src/providers/generic/connection/CdnProvider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ref } from 'vue';

import R2Error from '../../../model/errors/R2Error';
import { getAxiosWithTimeouts } from '../../../utils/HttpUtils';
import { addOrReplaceSearchParams, replaceHost } from '../../../utils/UrlUtils';
Expand All @@ -20,13 +22,13 @@ const CONNECTION_ERROR = new R2Error(

export default class CdnProvider {
private static axios = getAxiosWithTimeouts(5000, 5000);
private static preferredCdn = "";
private static preferredCdn = ref("");

public static get current() {
const i = CDNS.findIndex((cdn) => cdn === CdnProvider.preferredCdn);
const i = CDNS.findIndex((cdn) => cdn === CdnProvider.preferredCdn.value);
return {
label: [-1, 0].includes(i) ? "Main CDN" : `Mirror #${i}`,
url: CdnProvider.preferredCdn
url: CdnProvider.preferredCdn.value
};
}

Expand All @@ -49,7 +51,7 @@ export default class CdnProvider {
}

if (res.status === 200) {
CdnProvider.preferredCdn = cdn;
CdnProvider.preferredCdn.value = cdn;
return;
}
};
Expand All @@ -58,24 +60,24 @@ export default class CdnProvider {
}

public static replaceCdnHost(url: string) {
return CdnProvider.preferredCdn
? replaceHost(url, CdnProvider.preferredCdn)
return CdnProvider.preferredCdn.value
? replaceHost(url, CdnProvider.preferredCdn.value)
: url;
}

public static addCdnQueryParameter(url: string) {
return CdnProvider.preferredCdn
? addOrReplaceSearchParams(url, `cdn=${CdnProvider.preferredCdn}`)
return CdnProvider.preferredCdn.value
? addOrReplaceSearchParams(url, `cdn=${CdnProvider.preferredCdn.value}`)
: url;
}

public static togglePreferredCdn() {
let currentIndex = CDNS.findIndex((cdn) => cdn === CdnProvider.preferredCdn);
let currentIndex = CDNS.findIndex((cdn) => cdn === CdnProvider.preferredCdn.value);

if (currentIndex === -1) {
currentIndex = 0;
}

CdnProvider.preferredCdn = CDNS[currentIndex + 1] || CDNS[0];
CdnProvider.preferredCdn.value = CDNS[currentIndex + 1] || CDNS[0];
}
}
8 changes: 6 additions & 2 deletions src/store/modules/DownloadModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,16 @@ export const DownloadModule = {
commit('setDone', downloadId);
} catch (e) {
const r2Error = R2Error.fromThrownValue(e);
DownloadUtils.addSolutionsToError(r2Error);
if (downloadId) {
commit('setFailed', downloadId);
if (profile.getProfilePath() === rootGetters['profile/activeProfile'].getProfilePath()) {
r2Error.setAction({
r2Error.addAction({
label: 'Retry',
function: () => dispatch('retryDownloadById', downloadId)
function: async () => {
commit('error/discardError', null, { root: true });
await dispatch('retryDownloadById', downloadId);
},
});
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/utils/DownloadUtils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import CdnProvider from "../providers/generic/connection/CdnProvider";
import R2Error from "../model/errors/R2Error";

export function addSolutionsToError(err: R2Error): void {
Expand All @@ -10,7 +11,12 @@ export function addSolutionsToError(err: R2Error): void {
err.name.includes("Failed to download mod") ||
err.name.includes("System.Net.WebException")
) {
err.solution = "Try toggling the preferred Thunderstore CDN in the settings";
err.solution = "Try toggling the preferred Thunderstore CDN by clicking the button below (or in the settings).";
err.showCurrentCdn = true;
err.addAction({
label: 'Toggle CDN',
function: async () => CdnProvider.togglePreferredCdn(),
});
}

if (err.message.includes("System.IO.PathTooLongException")) {
Expand Down
Loading