feat: WIP global error handling

This commit is contained in:
Zack Spear
2023-07-07 17:30:45 -07:00
parent efb838c87c
commit 312178129e
5 changed files with 73 additions and 48 deletions

View File

@@ -1,6 +1,7 @@
import { defineStore, createPinia, setActivePinia } from 'pinia';
import { useCallbackStore } from './callbackActions';
import { useServerStore } from './server';
import { useCallbackStore } from '~/store/callbackActions';
import { useErrorsStore } from '~/store/errors';
import { useServerStore } from '~/store/server';
import { WebguiUpdate } from '~/composables/services/webgui';
import { ACCOUNT } from '~/helpers/urls';
import type { ExternalSignIn, ExternalSignOut } from '~/store/callback';
@@ -12,6 +13,7 @@ setActivePinia(createPinia());
export const useAccountStore = defineStore('account', () => {
const callbackStore = useCallbackStore();
const errorsStore = useErrorsStore();
const serverStore = useServerStore();
// State
@@ -108,26 +110,6 @@ export const useAccountStore = defineStore('account', () => {
accountAction.value = action;
accountActionStatus.value = 'updating';
const userPayload = {
...(accountAction.value.user
? {
apikey: accountAction.value.apiKey,
// avatar: '',
email: accountAction.value.user?.email,
regWizTime: `${Date.now()}_${serverStore.guid}`, // set when signing in the first time and never unset for the sake of displaying Sign In/Up in the UPC without needing to validate guid every time
username: accountAction.value.user?.preferred_username,
}
: {
accesstoken: '',
apikey: '',
avatar: '',
email: '',
idtoken: '',
refreshtoken: '',
username: '',
}),
};
if (!serverStore.registered && !accountAction.value.user) {
console.debug('[accountStore.updatePluginConfig] Not registered skipping sign out');
accountActionHide.value = true;
@@ -136,6 +118,25 @@ export const useAccountStore = defineStore('account', () => {
}
try {
const userPayload = {
...(accountAction.value.user
? {
apikey: accountAction.value.apiKey,
// avatar: '',
email: accountAction.value.user?.email,
regWizTime: `${Date.now()}_${serverStore.guid}`, // set when signing in the first time and never unset for the sake of displaying Sign In/Up in the UPC without needing to validate guid every time
username: accountAction.value.user?.preferred_username,
}
: {
accesstoken: '',
apikey: '',
avatar: '',
email: '',
idtoken: '',
refreshtoken: '',
username: '',
}),
};
const response = await WebguiUpdate
.formUrl({
csrf_token: serverStore.csrf,
@@ -151,11 +152,13 @@ export const useAccountStore = defineStore('account', () => {
.catch(err => {
console.debug('[accountStore.updatePluginConfig] WebguiUpdate err', err);
accountActionStatus.value = 'failed';
errorsStore.setError(err);
});
return response;
} catch(err) {
console.debug('[accountStore.updatePluginConfig] WebguiUpdate catch err', err);
accountActionStatus.value = 'failed';
errorsStore.setError(err);
}
};

View File

@@ -108,20 +108,25 @@ export const useCallbackStoreGeneric = (
const send = (url: string, payload: SendPayloads, sendType?: 'fromUpc' | 'forUpc') => {
console.debug('[callback.send]');
const stringifiedData = JSON.stringify({
actions: [
...payload,
],
sender: window.location.href,
type: sendType ?? defaultSendType,
});
const encryptedMessage = AES.encrypt(stringifiedData, encryptionKey).toString();
// build and go to url
const destinationUrl = new URL(url);
destinationUrl.searchParams.set('data', encodeURI(encryptedMessage));
console.debug('[callback.send]', encryptedMessage, destinationUrl);
window.location.href = destinationUrl.toString();
return;
try {
const stringifiedData = JSON.stringify({
actions: [
...payload,
],
sender: window.location.href,
type: sendType ?? defaultSendType,
});
const encryptedMessage = AES.encrypt(stringifiedData, encryptionKey).toString();
// build and go to url
const destinationUrl = new URL(url);
destinationUrl.searchParams.set('data', encodeURI(encryptedMessage));
console.debug('[callback.send]', encryptedMessage, destinationUrl);
window.location.href = destinationUrl.toString();
return;
} catch (error) {
console.error(error);
throw new Error("Unable to create callback event");
}
};
const watcher = () => {
@@ -133,11 +138,16 @@ export const useCallbackStoreGeneric = (
return console.debug('[callback.watcher] no callback to handle');
}
const decryptedMessage = AES.decrypt(callbackValue, encryptionKey);
const decryptedData: QueryPayloads = JSON.parse(decryptedMessage.toString(Utf8));
console.debug('[callback.watcher]', decryptedMessage, decryptedData);
// Parse the data and perform actions
callbackActions.redirectToCallbackType(decryptedData);
try {
const decryptedMessage = AES.decrypt(callbackValue, encryptionKey);
const decryptedData: QueryPayloads = JSON.parse(decryptedMessage.toString(Utf8));
console.debug('[callback.watcher]', decryptedMessage, decryptedData);
// Parse the data and perform actions
callbackActions.redirectToCallbackType(decryptedData);
} catch (error) {
console.error(error);
throw new Error("Couldn't decrypt callback data");
}
};
return {

View File

@@ -4,15 +4,13 @@ import { addPreventClose, removePreventClose } from '~/composables/preventClose'
import { useAccountStore } from '~/store/account';
import { useInstallKeyStore } from '~/store/installKey';
import { useCallbackStoreGeneric, type ExternalPayload, type ExternalKeyActions, type QueryPayloads } from '~/store/callback';
import { remove } from '@vue/shared';
// import { useServerStore } from './server';
export const useCallbackActionsStore = defineStore(
'callbackActions',
() => {
const accountStore = useAccountStore();
const installKeyStore = useInstallKeyStore();
// const serverStore = useServerStore();
type CallbackStatus = 'error' | 'loading' | 'ready' | 'success';
const callbackStatus = ref<CallbackStatus>('ready');

View File

@@ -1,8 +1,8 @@
import { defineStore, createPinia, setActivePinia } from 'pinia';
// import { useAccountStore } from './account';
// import { useCallbackStore } from './callbackActions';
// import { useInstallKeyStore } from './installKey';
// import { useServerStore } from './server';
// import { useAccountStore } from '~/store/account';
// import { useCallbackStore, useCallbackActionsStore } from '~/store/callbackActions';
// import { useInstallKeyStore } from '~/store/installKey';
// import { useServerStore } from '~/store/server';
/**
* @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components
@@ -13,18 +13,29 @@ setActivePinia(createPinia());
export const useErrorsStore = defineStore('errors', () => {
// const accountStore = useAccountStore();
// const callbackStore = useCallbackStore();
// const callbackActionsStore = useCallbackActionsStore();
// const installKeyStore = useInstallKeyStore();
// const serverStore = useServerStore();
/** @todo type the errors */
const errors = ref<any[]>([]);
const removeError = (index: number) => {
errors.value = errors.value.filter((_error, i) => i !== index);
};
const resetErrors = () => {
errors.value = [];
};
const setError = (error: any) => {
errors.value.push(error);
};
return {
errors,
removeError,
resetErrors,
setError,
};
});

View File

@@ -1,6 +1,7 @@
import { defineStore, createPinia, setActivePinia } from 'pinia';
import { delay } from 'wretch/middlewares';
import { WebguiInstallKey, WebguiUpdateDns } from '~/composables/services/webgui';
import { useErrorsStore } from '~/store/errors';
import { useServerStore } from '~/store/server';
import type { ExternalKeyActions } from '~/store/callback';
/**
@@ -10,6 +11,7 @@ import type { ExternalKeyActions } from '~/store/callback';
setActivePinia(createPinia());
export const useInstallKeyStore = defineStore('installKey', () => {
const errorsStore = useErrorsStore();
const serverStore = useServerStore();
const keyInstallStatus = ref<'failed' | 'installing' | 'ready' | 'success'>('ready');
@@ -55,6 +57,7 @@ export const useInstallKeyStore = defineStore('installKey', () => {
} catch (error) {
console.error('[install] WebguiInstallKey error', error);
keyInstallStatus.value = 'failed';
errorsStore.setError(error);
}
};