refactor(dashboard): use onError on server actions
This commit is contained in:
parent
25c39b92e5
commit
76f9637d77
12 changed files with 106 additions and 83 deletions
|
@ -1,4 +1,4 @@
|
|||
import { SocketEvent } from '@runtipi/shared';
|
||||
import { SocketEvent } from '@runtipi/shared/src/schemas/socket';
|
||||
import { Socket } from 'socket.io';
|
||||
import { logger } from '../logger';
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import pg from 'pg';
|
||||
import { execAsync, pathExists, SocketEvent } from '@runtipi/shared';
|
||||
import { execAsync, pathExists } from '@runtipi/shared';
|
||||
import { SocketEvent } from '@runtipi/shared/src/schemas/socket';
|
||||
import { copyDataDir, generateEnvFile } from './app.helpers';
|
||||
import { logger } from '@/lib/logger';
|
||||
import { compose } from '@/lib/docker';
|
||||
|
@ -34,7 +35,7 @@ export class AppExecutors {
|
|||
this.logger = logger;
|
||||
}
|
||||
|
||||
private handleAppError = (err: unknown, appId: string, event: SocketEvent['event']) => {
|
||||
private handleAppError = (err: unknown, appId: string, event: Extract<SocketEvent, { type: 'app' }>['event']) => {
|
||||
if (err instanceof Error) {
|
||||
SocketManager.emit({ type: 'app', event, data: { appId, error: err.message } });
|
||||
this.logger.error(`An error occurred: ${err.message}`);
|
||||
|
|
|
@ -4209,6 +4209,11 @@ packages:
|
|||
/base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
/base64id@2.0.0:
|
||||
resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
|
||||
engines: {node: ^4.5.0 || >= 5.9}
|
||||
dev: false
|
||||
|
||||
/binary-extensions@2.2.0:
|
||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -4673,6 +4678,14 @@ packages:
|
|||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||
dev: true
|
||||
|
||||
/cors@2.8.5:
|
||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
dependencies:
|
||||
object-assign: 4.1.1
|
||||
vary: 1.1.2
|
||||
dev: false
|
||||
|
||||
/cosmiconfig@7.1.0:
|
||||
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
|
@ -14,10 +14,11 @@ export function LoginContainer() {
|
|||
const router = useRouter();
|
||||
|
||||
const loginMutation = useAction(loginAction, {
|
||||
onError: (e) => {
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
} else if (data.success && data.totpSessionId) {
|
||||
if (data.success && data.totpSessionId) {
|
||||
setTotpSessionId(data.totpSessionId);
|
||||
} else {
|
||||
router.push('/dashboard');
|
||||
|
@ -26,18 +27,27 @@ export function LoginContainer() {
|
|||
});
|
||||
|
||||
const verifyTotpMutation = useAction(verifyTotpAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
router.push('/dashboard');
|
||||
}
|
||||
onError: (e) => {
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
router.push('/dashboard');
|
||||
},
|
||||
});
|
||||
|
||||
if (totpSessionId) {
|
||||
return <TotpForm loading={verifyTotpMutation.status === 'executing'} onSubmit={(totpCode) => verifyTotpMutation.execute({ totpCode, totpSessionId })} />;
|
||||
return (
|
||||
<TotpForm
|
||||
loading={verifyTotpMutation.status === 'executing'}
|
||||
onSubmit={(totpCode) => verifyTotpMutation.execute({ totpCode, totpSessionId })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <LoginForm loading={loginMutation.status === 'executing'} onSubmit={({ email, password }) => loginMutation.execute({ username: email, password })} />;
|
||||
return (
|
||||
<LoginForm
|
||||
loading={loginMutation.status === 'executing'}
|
||||
onSubmit={({ email, password }) => loginMutation.execute({ username: email, password })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,14 +11,18 @@ export const RegisterContainer: React.FC = () => {
|
|||
const router = useRouter();
|
||||
|
||||
const registerMutation = useAction(registerAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
router.push('/dashboard');
|
||||
}
|
||||
onError: (e) => {
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
router.push('/dashboard');
|
||||
},
|
||||
});
|
||||
|
||||
return <RegisterForm onSubmit={({ email, password }) => registerMutation.execute({ username: email, password })} loading={registerMutation.status === 'executing'} />;
|
||||
return (
|
||||
<RegisterForm
|
||||
onSubmit={({ email, password }) => registerMutation.execute({ username: email, password })}
|
||||
loading={registerMutation.status === 'executing'}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -15,18 +15,14 @@ export const ResetPasswordContainer: React.FC = () => {
|
|||
const router = useRouter();
|
||||
|
||||
const resetPasswordMutation = useAction(resetPasswordAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
}
|
||||
onError: (error) => {
|
||||
if (error.serverError) toast.error(error.serverError);
|
||||
},
|
||||
});
|
||||
|
||||
const cancelRequestMutation = useAction(cancelResetPasswordAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
}
|
||||
onError: (error) => {
|
||||
if (error.serverError) toast.error(error.serverError);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const installMutation = useAction(installAppAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
setOptimisticStatus('installing');
|
||||
|
@ -55,7 +55,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const uninstallMutation = useAction(uninstallAppAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
uninstallDisclosure.close();
|
||||
|
@ -65,7 +65,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const stopMutation = useAction(stopAppAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
stopDisclosure.close();
|
||||
|
@ -75,7 +75,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const startMutation = useAction(startAppAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
setOptimisticStatus('starting');
|
||||
|
@ -84,7 +84,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const updateMutation = useAction(updateAppAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
updateDisclosure.close();
|
||||
|
@ -94,7 +94,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const updateConfigMutation = useAction(updateAppConfigAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
updateSettingsDisclosure.close();
|
||||
|
@ -106,7 +106,7 @@ export const AppDetailsContainer: React.FC<AppDetailsContainerProps> = ({ app, l
|
|||
|
||||
const resetMutation = useAction(resetAppAction, {
|
||||
onError: (e) => {
|
||||
toast.error(e.serverError!);
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onExecute: () => {
|
||||
resetAppDisclosure.open();
|
||||
|
|
|
@ -34,13 +34,12 @@ export const ChangePasswordForm = () => {
|
|||
const router = useRouter();
|
||||
|
||||
const changePasswordMutation = useAction(changePasswordAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
toast.success(t('password-change-success'));
|
||||
router.push('/');
|
||||
}
|
||||
onError: (e) => {
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t('password-change-success'));
|
||||
router.push('/');
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -27,13 +27,12 @@ export const ChangeUsernameForm = ({ username }: Props) => {
|
|||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
const changeUsernameMutation = useAction(changeUsernameAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
toast.success(t('change-username.success'));
|
||||
router.push('/');
|
||||
}
|
||||
onError: (e) => {
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t('change-username.success'));
|
||||
router.push('/');
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -29,28 +29,26 @@ export const OtpForm = (props: { totpEnabled: boolean }) => {
|
|||
onExecute: () => {
|
||||
setupOtpDisclosure.close();
|
||||
},
|
||||
onError: (e) => {
|
||||
setPassword('');
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
setPassword('');
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
setKey(data.key);
|
||||
setUri(data.uri);
|
||||
}
|
||||
setKey(data.key);
|
||||
setUri(data.uri);
|
||||
},
|
||||
});
|
||||
|
||||
const setupTotpMutation = useAction(setupTotpAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
setTotpCode('');
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
setTotpCode('');
|
||||
setKey('');
|
||||
setUri('');
|
||||
toast.success(t('2fa-enable-success'));
|
||||
}
|
||||
onError: (e) => {
|
||||
setTotpCode('');
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
setTotpCode('');
|
||||
setKey('');
|
||||
setUri('');
|
||||
toast.success(t('2fa-enable-success'));
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -58,13 +56,12 @@ export const OtpForm = (props: { totpEnabled: boolean }) => {
|
|||
onExecute: () => {
|
||||
disableOtpDisclosure.close();
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
setPassword('');
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
toast.success(t('2fa-disable-success'));
|
||||
}
|
||||
onError: (e) => {
|
||||
setPassword('');
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t('2fa-disable-success'));
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -20,13 +20,12 @@ export const SettingsContainer = ({ initialValues, currentLocale }: Props) => {
|
|||
const router = useRouter();
|
||||
|
||||
const updateSettingsMutation = useAction(updateSettingsAction, {
|
||||
onSuccess: (data) => {
|
||||
if (!data.success) {
|
||||
toast.error(data.failure.reason);
|
||||
} else {
|
||||
toast.success(t('settings.settings.settings-updated'));
|
||||
router.refresh();
|
||||
}
|
||||
onError: (e) => {
|
||||
if (e.serverError) toast.error(e.serverError);
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(t('settings.settings.settings-updated'));
|
||||
router.refresh();
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -36,7 +35,12 @@ export const SettingsContainer = ({ initialValues, currentLocale }: Props) => {
|
|||
|
||||
return (
|
||||
<div className="card-body">
|
||||
<SettingsForm initalValues={initialValues} currentLocale={currentLocale} loading={updateSettingsMutation.status === 'executing'} onSubmit={onSubmit} />
|
||||
<SettingsForm
|
||||
initalValues={initialValues}
|
||||
currentLocale={currentLocale}
|
||||
loading={updateSettingsMutation.status === 'executing'}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ export const action = createSafeActionClient({
|
|||
console.error('Error from server', e);
|
||||
|
||||
return {
|
||||
serverError: e.message,
|
||||
serverError: e.message || 'An unexpected error occurred',
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue