@@ -42,7 +41,6 @@ import Component from "vue-class-component";
import ManifestV2 from "../../model/ManifestV2";
import LocalModListProvider from "../../providers/components/loaders/LocalModListProvider";
-import ThunderstoreDownloaderProvider from "../../providers/ror2/downloading/ThunderstoreDownloaderProvider";
@Component({
components: {
diff --git a/src/components/views/LocalModList.vue b/src/components/views/LocalModList.vue
index 643c22fe..dfbbc3a5 100644
--- a/src/components/views/LocalModList.vue
+++ b/src/components/views/LocalModList.vue
@@ -1,7 +1,7 @@
-
+
{
const result = await ProfileModList.saveModList(this.contextProfile!, newList);
if (result instanceof R2Error) {
- this.emitError(result);
+ this.$store.commit('error/handleError', result);
return;
}
this.updateModListAfterChange(newList);
@@ -125,7 +124,7 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
const err = await ConflictManagementProvider.instance.resolveConflicts(updatedList, this.contextProfile!);
if (err instanceof R2Error) {
- this.$emit('error', err);
+ this.$store.commit('error/handleError', err);
}
}
@@ -142,14 +141,14 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
if (uninstallError instanceof R2Error) {
// Uninstall failed
this.showingDependencyList = false;
- this.$emit('error', uninstallError);
+ this.$store.commit('error/handleError', uninstallError);
return uninstallError;
}
const modList: ManifestV2[] | R2Error = await ProfileModList.removeMod(mod, this.contextProfile!);
if (modList instanceof R2Error) {
// Failed to remove mod from local list.
this.showingDependencyList = false;
- this.$emit('error', modList);
+ this.$store.commit('error/handleError', modList);
return modList;
}
if (updateModList) {
@@ -173,7 +172,7 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
this.modBeingUninstalled = mod.getName();
const result = await this.performUninstallMod(mod, false);
if (result instanceof R2Error) {
- this.$emit('error', result);
+ this.$store.commit('error/handleError', result);
this.modBeingUninstalled = null;
return;
} else {
@@ -181,10 +180,10 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
}
}
} catch (e) {
- // Failed to uninstall mod.
- const err: Error = e as Error;
- this.$emit('error', err);
- LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `${err.name}\n-> ${err.message}`);
+ this.$store.commit('error/handleError', {
+ error: R2Error.fromThrownValue(e),
+ severity: LogSeverity.ACTION_STOPPED
+ });
} finally {
this.modBeingUninstalled = null;
if (lastSuccess) {
@@ -194,7 +193,7 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
this.selectedManifestMod = null;
const result: ManifestV2[] | R2Error = await ProfileModList.getModList(this.contextProfile!);
if (result instanceof R2Error) {
- this.$emit('error', result);
+ this.$store.commit('error/handleError', result);
return;
}
await this.updateModListAfterChange(result);
@@ -225,21 +224,21 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
throw result;
}
} catch (e) {
- // Failed to disable mod.
- const err: Error = e as Error;
- this.$emit('error', err);
- LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `${err.name}\n-> ${err.message}`);
+ this.$store.commit('error/handleError', {
+ error: R2Error.fromThrownValue(e),
+ severity: LogSeverity.ACTION_STOPPED
+ });
}
}
async performEnable(mods: ManifestV2[]): Promise {
for (let mod of mods) {
- const disableErr: R2Error | void = await ProfileInstallerProvider.instance.enableMod(mod, this.contextProfile!);
- if (disableErr instanceof R2Error) {
+ const enableErr: R2Error | void = await ProfileInstallerProvider.instance.enableMod(mod, this.contextProfile!);
+ if (enableErr instanceof R2Error) {
// Failed to disable
this.showingDependencyList = false;
- this.$emit('error', disableErr);
- return disableErr;
+ this.$store.commit('error/handleError', enableErr);
+ return enableErr;
}
}
const updatedList = await ProfileModList.updateMods(mods, this.contextProfile!, (updatingMod: ManifestV2) => {
@@ -248,7 +247,7 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
if (updatedList instanceof R2Error) {
// Failed to update mod list.
this.showingDependencyList = false;
- this.$emit('error', updatedList);
+ this.$store.commit('error/handleError', updatedList);
return updatedList;
}
await this.updateModListAfterChange(updatedList);
@@ -276,7 +275,7 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
'You may be offline, or the mod was removed from Thunderstore.',
'The dependency may not yet be published to Thunderstore and may be available elsewhere.'
);
- this.$emit('error', error);
+ this.$store.commit('error/handleError', error);
return;
}
this.$store.commit("openDownloadModModal", tsMod);
@@ -289,11 +288,6 @@ import SearchAndSort from './LocalModList/SearchAndSort.vue';
this.cardExpanded = this.settings.getContext().global.expandedCards;
this.funkyMode = this.settings.getContext().global.funkyModeEnabled;
}
-
- emitError(error: R2Error) {
- this.$emit('error', error);
- }
-
}
diff --git a/src/components/views/LocalModList/DisableModModal.vue b/src/components/views/LocalModList/DisableModModal.vue
index 7ea7226b..29c43547 100644
--- a/src/components/views/LocalModList/DisableModModal.vue
+++ b/src/components/views/LocalModList/DisableModModal.vue
@@ -53,9 +53,10 @@ export default class DisableModModal extends Vue {
{ mods, onProgress }
);
} catch (e) {
- const err: Error = e as Error;
- LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `${err.name}\n-> ${err.message}`);
- this.$emit('error', e);
+ this.$store.commit('error/handleError', {
+ error: R2Error.fromThrownValue(e),
+ severity: LogSeverity.ACTION_STOPPED
+ });
} finally {
this.onClose();
this.modBeingDisabled = null;
diff --git a/src/components/views/LocalModList/LocalModCard.vue b/src/components/views/LocalModList/LocalModCard.vue
index 4f352ff9..2d7bb1a9 100644
--- a/src/components/views/LocalModList/LocalModCard.vue
+++ b/src/components/views/LocalModList/LocalModCard.vue
@@ -2,8 +2,9 @@
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { ExpandableCard, Link } from '../../all';
import DonateButton from '../../buttons/DonateButton.vue';
+import R2Error from '../../../model/errors/R2Error';
import ManifestV2 from '../../../model/ManifestV2';
-import LoggerProvider, { LogSeverity } from '../../../providers/ror2/logging/LoggerProvider';
+import { LogSeverity } from '../../../providers/ror2/logging/LoggerProvider';
import Dependants from '../../../r2mm/mods/Dependants';
import ModBridge from '../../../r2mm/mods/ModBridge';
@@ -91,9 +92,10 @@ export default class LocalModCard extends Vue {
{ mods: [this.mod] }
);
} catch (e) {
- this.$emit('error', e);
- const err: Error = e as Error;
- LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `${err.name}\n-> ${err.message}`);
+ this.$store.commit('error/handleError', {
+ error: R2Error.fromThrownValue(e),
+ severity: LogSeverity.ACTION_STOPPED
+ });
}
}
diff --git a/src/components/views/OnlineModList.vue b/src/components/views/OnlineModList.vue
index 44523979..7ce81188 100644
--- a/src/components/views/OnlineModList.vue
+++ b/src/components/views/OnlineModList.vue
@@ -68,7 +68,6 @@ import ManagerSettings from '../../r2mm/manager/ManagerSettings';
import { ExpandableCard, Link } from '../all';
import DownloadModModal from './DownloadModModal.vue';
import ManifestV2 from '../../model/ManifestV2';
-import R2Error from '../../model/errors/R2Error';
import DonateButton from '../../components/buttons/DonateButton.vue';
import CdnProvider from '../../providers/generic/connection/CdnProvider';
@@ -129,10 +128,6 @@ export default class OnlineModList extends Vue {
);
}
- emitError(error: R2Error) {
- this.$emit('error', error);
- }
-
async created() {
this.settings = await ManagerSettings.getSingleton(GameManager.activeGame);
this.cardExpanded = this.settings.getContext().global.expandedCards;
diff --git a/src/components/views/OnlineModView.vue b/src/components/views/OnlineModView.vue
index 102aff53..edcf8a8e 100644
--- a/src/components/views/OnlineModView.vue
+++ b/src/components/views/OnlineModView.vue
@@ -46,7 +46,6 @@
diff --git a/src/pages/GameSelectionScreen.vue b/src/pages/GameSelectionScreen.vue
index 09c1e6c1..1649fb4d 100644
--- a/src/pages/GameSelectionScreen.vue
+++ b/src/pages/GameSelectionScreen.vue
@@ -277,7 +277,7 @@ export default class GameSelectionScreen extends Vue {
ProviderUtils.setupGameProviders(this.selectedGame, this.selectedPlatform);
} catch (error) {
if (error instanceof R2Error) {
- this.$emit("error", error);
+ this.$store.commit('error/handleError', error);
return;
}
diff --git a/src/pages/Manager.vue b/src/pages/Manager.vue
index 54002222..bc767a34 100644
--- a/src/pages/Manager.vue
+++ b/src/pages/Manager.vue
@@ -128,11 +128,10 @@
-
-
+
+
@@ -149,7 +148,7 @@ import ProfileInstallerProvider from '../providers/ror2/installing/ProfileInstal
import PathResolver from '../r2mm/manager/PathResolver';
import PreloaderFixer from '../r2mm/manager/PreloaderFixer';
-import LoggerProvider, { LogSeverity } from '../providers/ror2/logging/LoggerProvider';
+import { LogSeverity } from '../providers/ror2/logging/LoggerProvider';
import Profile from '../model/Profile';
import VersionNumber from '../model/VersionNumber';
@@ -215,10 +214,6 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
return this.$store.state.localModList || [];
}
- showError(error: R2Error) {
- this.$emit("error", error);
- }
-
closePreloaderFixModal() {
this.fixingPreloader = false;
}
@@ -226,7 +221,7 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
async fixPreloader() {
const res = await PreloaderFixer.fix(this.activeGame);
if (res instanceof R2Error) {
- this.showError(res);
+ this.$store.commit('error/handleError', res);
} else {
this.fixingPreloader = true;
}
@@ -277,12 +272,8 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
this.showRor2IncorrectDirectoryModal = true;
}
} catch (e) {
- const err: Error = e as Error;
- this.showError(new R2Error(
- "Failed to change the game directory",
- err.message,
- null
- ));
+ const err = R2Error.fromThrownValue(e, 'Failed to change the game directory');
+ this.$store.commit('error/handleError', err);
}
}
});
@@ -305,12 +296,8 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
throw new Error("The selected executable is not gamelaunchhelper.exe");
}
} catch (e) {
- const err: Error = e as Error;
- this.showError(new R2Error(
- "Failed to change the game directory",
- err.message,
- null
- ));
+ const err = R2Error.fromThrownValue(e, 'Failed to change the game directory');
+ this.$store.commit('error/handleError', err);
}
}
});
@@ -361,12 +348,8 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
this.showSteamIncorrectDirectoryModal = true;
}
} catch (e) {
- const err: Error = e as Error;
- this.showError(new R2Error(
- "Failed to change the Steam directory",
- err.message,
- null
- ));
+ const err = R2Error.fromThrownValue(e, 'Failed to change the Steam directory');
+ this.$store.commit('error/handleError', err);
}
}
});
@@ -379,21 +362,21 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
async exportProfile() {
const exportErr = await ProfileModList.exportModListToFile(this.contextProfile!);
if (exportErr instanceof R2Error) {
- this.showError(exportErr);
+ this.$store.commit('error/handleError', exportErr);
}
}
async exportProfileAsCode() {
const exportErr = await ProfileModList.exportModListAsCode(this.contextProfile!, (code: string, err: R2Error | null) => {
if (err !== null) {
- this.showError(err);
+ this.$store.commit('error/handleError', err);
} else {
this.exportCode = code;
InteractionProvider.instance.copyToClipboard(code);
}
});
if (exportErr instanceof R2Error) {
- this.showError(exportErr);
+ this.$store.commit('error/handleError', exportErr);
}
}
@@ -510,18 +493,18 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
const profileErr = await ProfileInstallerProvider.instance.enableMod(mod, this.contextProfile!);
if (profileErr instanceof R2Error) {
- this.showError(profileErr);
+ this.$store.commit('error/handleError', profileErr);
continue;
}
const update = await ProfileModList.updateMod(mod, this.contextProfile!, async (mod) => mod.enable());
if (update instanceof R2Error) {
- this.showError(update);
+ this.$store.commit('error/handleError', update);
} else {
lastSuccessfulUpdate = update;
}
}
} catch (e) {
- this.showError(R2Error.fromThrownValue(e, "Error enabling mods"));
+ this.$store.commit('error/handleError', R2Error.fromThrownValue(e, "Error enabling mods"));
} finally {
if (lastSuccessfulUpdate.length) {
await this.$store.dispatch("updateModList", lastSuccessfulUpdate);
@@ -553,8 +536,11 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
await fs.writeFile(path.join(files[0], dataDirectoryOverrideFile), "");
InteractionProvider.instance.restartApp();
} else {
- this.showError(new R2Error("Selected directory is not empty", `Directory is not empty: ${files[0]}. Contains ${filesInDirectory.length} files.`, "Select an empty directory or create a new one."));
- return;
+ this.$store.commit('error/handleError', new R2Error(
+ "Selected directory is not empty",
+ `Directory is not empty: ${files[0]}. Contains ${filesInDirectory.length} files.`,
+ "Select an empty directory or create a new one."
+ ));
}
}
});
@@ -656,16 +642,21 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
if (!(newModList instanceof R2Error)) {
await this.$store.dispatch("updateModList", newModList);
} else {
- LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `Failed to retrieve local mod list\n-> ${newModList.message}`);
- this.$emit('error', newModList);
+ this.$store.commit('error/handleError', {
+ error: newModList,
+ severity: LogSeverity.ACTION_STOPPED,
+ logMessage: `Failed to retrieve local mod list\n-> ${newModList.message}`
+ });
}
this.$store.commit("modFilters/reset");
InteractionProvider.instance.hookModInstallProtocol(async data => {
const combo: ThunderstoreCombo | R2Error = ThunderstoreCombo.fromProtocol(data, this.thunderstoreModList);
if (combo instanceof R2Error) {
- this.showError(combo);
- LoggerProvider.instance.Log(LogSeverity.ACTION_STOPPED, `${combo.name}\n-> ${combo.message}`);
+ this.$store.commit('error/handleError', {
+ error: combo,
+ severity: LogSeverity.ACTION_STOPPED
+ });
return;
}
DownloadModModal.downloadSpecific(this.activeGame, this.contextProfile!, combo, this.thunderstoreModList)
@@ -674,10 +665,12 @@ import CategoryFilterModal from '../components/modals/CategoryFilterModal.vue';
if (!(modList instanceof R2Error)) {
await this.$store.dispatch('updateModList', modList);
} else {
- this.showError(modList);
+ this.$store.commit('error/handleError', modList);
}
})
- .catch(this.showError);
+ .catch(
+ (err: R2Error) => this.$store.commit('error/handleError', err)
+ );
});
this.isManagerUpdateAvailable();
diff --git a/src/pages/Profiles.vue b/src/pages/Profiles.vue
index 1fd6605e..39705653 100644
--- a/src/pages/Profiles.vue
+++ b/src/pages/Profiles.vue
@@ -156,18 +156,6 @@
-
-
-
-
-
-
Error
-
{{errorMessage}}
-
{{errorStack}}
-
-
-
-
@@ -313,18 +301,10 @@ export default class Profiles extends Vue {
private activeGame!: Game;
- errorMessage: string = '';
- errorStack: string = '';
-
get appName(): string {
return ManagerInformation.APP_NAME;
}
- showError(error: R2Error) {
- this.errorMessage = error.name;
- this.errorStack = error.message;
- }
-
doesProfileExist(nameToCheck: string): boolean {
if ((nameToCheck.match(new RegExp('^([a-zA-Z0-9])(\\s|[a-zA-Z0-9]|_|-|[.])*$'))) === null) {
return true;
@@ -409,10 +389,8 @@ export default class Profiles extends Vue {
await FileUtils.emptyDirectory(Profile.getActiveProfile().getPathOfProfile());
await fs.rmdir(Profile.getActiveProfile().getPathOfProfile());
} catch (e) {
- const err: Error = e as Error;
- this.showError(
- new R2Error('Error whilst deleting profile', err.message, null)
- );
+ const err = R2Error.fromThrownValue(e, 'Error whilst deleting profile');
+ this.$store.commit('error/handleError', err);
}
if (
Profile.getActiveProfile()
@@ -456,7 +434,7 @@ export default class Profiles extends Vue {
if (status == StatusEnum.FAILURE) {
this.importingProfile = false;
if (err instanceof R2Error) {
- this.showError(err);
+ this.$store.commit('error/handleError', err);
}
} else if (status == StatusEnum.PENDING) {
this.percentageImported = Math.floor(progress);
@@ -469,7 +447,7 @@ export default class Profiles extends Vue {
}
const installResult: R2Error | ManifestV2 = await this.installModAfterDownload(comboMod.getMod(), comboMod.getVersion());
if (installResult instanceof R2Error) {
- this.showError(installResult);
+ this.$store.commit('error/handleError', installResult);
keepIterating = false;
this.importingProfile = false;
return;
@@ -507,7 +485,8 @@ export default class Profiles extends Vue {
const filepath = await ProfileImportExport.downloadProfileCode(this.profileImportCode.trim());
await this.importProfileHandler([filepath]);
} catch (e: any) {
- this.showError(R2Error.fromThrownValue(e, "Failed to import profile"));
+ const err = R2Error.fromThrownValue(e, 'Failed to import profile');
+ this.$store.commit('error/handleError', err);
}
}
@@ -622,9 +601,8 @@ export default class Profiles extends Vue {
}) as EventListener), {once: true});
}
} catch (e) {
- const err = new R2Error("Failed to import profile", (e as Error).message, null);
- this.showError(err);
- return;
+ const err = R2Error.fromThrownValue(e, 'Failed to import profile');
+ this.$store.commit('error/handleError', err);
}
}
diff --git a/src/store/index.ts b/src/store/index.ts
index 1d85d351..4c9bbdd3 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -1,6 +1,7 @@
import Vue from 'vue';
import Vuex, { ActionContext } from 'vuex';
+import ErrorModule from './modules/ErrorModule';
import ModalsModule from './modules/ModalsModule';
import ModFilterModule from './modules/ModFilterModule';
import ProfileModule from './modules/ProfileModule';
@@ -94,6 +95,7 @@ export const store = {
}
},
modules: {
+ error: ErrorModule,
modals: ModalsModule,
modFilters: ModFilterModule,
profile: ProfileModule,
diff --git a/src/store/modules/ErrorModule.ts b/src/store/modules/ErrorModule.ts
new file mode 100644
index 00000000..89a7e77f
--- /dev/null
+++ b/src/store/modules/ErrorModule.ts
@@ -0,0 +1,40 @@
+import R2Error from "../../model/errors/R2Error";
+import LoggerProvider, { LogSeverity } from '../../providers/ror2/logging/LoggerProvider';
+
+interface State {
+ error: R2Error | null;
+}
+
+interface ErrorWithLogging {
+ error: R2Error;
+ severity: LogSeverity;
+ logMessage?: string;
+}
+
+export default {
+ namespaced: true,
+
+ state: (): State => ({
+ error: null,
+ }),
+
+ mutations: {
+ discardError: function(state: State): void {
+ state.error = null;
+ },
+
+ handleError: function(
+ state: State,
+ error: R2Error | ErrorWithLogging
+ ): void {
+ state.error = error instanceof R2Error ? error : error.error;
+
+ if (error instanceof R2Error) {
+ LoggerProvider.instance.Log(LogSeverity.ERROR, `[${error.name}]: ${error.message}`);
+ } else {
+ const msg = error.logMessage || `[${error.error.name}]: ${error.error.message}`;
+ LoggerProvider.instance.Log(error.severity, msg);
+ }
+ },
+ }
+}