Skip to content

Commit

Permalink
Merge pull request #580 from VitNode/fix/handle_error_from_server_fun…
Browse files Browse the repository at this point in the history
…ction

fix(frontend): Handle errors from server functions on production
  • Loading branch information
aXenDeveloper authored Nov 22, 2024
2 parents 9605d66 + 0c08ca3 commit da811db
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 174 deletions.
2 changes: 1 addition & 1 deletion apps/frontend/DockerFile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RUN turbo prune frontend --docker
FROM base AS installer
WORKDIR /app
COPY --from=builder /app/out/json/ .
RUN pnpm i
RUN pnpm i --ignore-scripts
COPY --from=builder /app/out/full/ .
COPY --from=builder /app/.prettierrc.mjs ./

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RUN turbo prune frontend --docker
FROM base AS installer
WORKDIR /app
COPY --from=builder /app/out/json/ .
RUN pnpm i
RUN pnpm i --ignore-scripts
COPY --from=builder /app/out/full/ .
COPY --from=builder /app/.prettierrc.mjs ./

Expand Down
2 changes: 1 addition & 1 deletion packages/create-vitnode-app/templates/docker/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ else
echo ".env file already exists. Skipping creation."
fi

sudo docker-compose -f ./docker-compose.yml -p vitnode up -d
sudo docker-compose -f ./docker-compose.yml -p vitnode up --build -d

sudo chown -R 1001:1001 ./apps/backend/src/plugins/core
sudo chown -R 1001:1001 ./apps/backend/uploads
Expand Down
53 changes: 34 additions & 19 deletions packages/frontend/src/hooks/sign/in/mutation-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,43 @@ import { cookies } from 'next/headers';
import { SignInAuthBody } from 'vitnode-shared/auth/auth.dto';

export const mutationApi = async (body: SignInAuthBody) => {
await fetcher<object, SignInAuthBody>({
method: 'POST',
url: '/core/auth/sign_in',
body,
});

const cookie = await cookies();
if (body.admin) {
const adminIdFromCookie = await getAdminIdCookie();
if (adminIdFromCookie) {
revalidateTags.sessionAdmin(+adminIdFromCookie);
try {
await fetcher<object, SignInAuthBody>({
method: 'POST',
url: '/core/auth/sign_in',
body,
});

const cookie = await cookies();
if (body.admin) {
const adminIdFromCookie = await getAdminIdCookie();
if (adminIdFromCookie) {
revalidateTags.sessionAdmin(+adminIdFromCookie);
}

await redirect('/admin/core/dashboard');

return;
}

await redirect('/admin/core/dashboard');
const userIdFromCookie = cookie.get('vitnode-user-id')?.value;
if (userIdFromCookie) {
revalidateTags.session(+userIdFromCookie);
}
await redirect('/');
} catch (err) {
const { message } = err as Error;
if (message === 'NEXT_REDIRECT') {
await redirect('/');
}
if (message.includes('EMAIL_NOT_VERIFIED')) {
return { message: 'EMAIL_NOT_VERIFIED' };
}

return;
}
if (message.includes('ACCESS_DENIED')) {
return { message: 'ACCESS_DENIED' };
}

const userIdFromCookie = cookie.get('vitnode-user-id')?.value;
if (userIdFromCookie) {
revalidateTags.session(+userIdFromCookie);
return { message: 'INTERNAL_SERVER_ERROR' };
}

await redirect('/');
};
22 changes: 9 additions & 13 deletions packages/frontend/src/hooks/sign/in/use-sign-in-admin-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,17 @@ export const useSignInAdminView = () => {
});

const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
await mutationApi({ ...values, admin: true });
} catch (e) {
const { message } = e as Error;
if (message === 'NEXT_REDIRECT') return;
if (message.includes('ACCESS_DENIED')) {
setError('ACCESS_DENIED');
const mutation = await mutationApi({ ...values, admin: true });
if (!mutation?.message) return;
if (mutation.message === 'ACCESS_DENIED') {
setError('ACCESS_DENIED');

return;
}

toast.error(t('title'), {
description: t('internal_server_error'),
});
return;
}

toast.error(t('title'), {
description: t('internal_server_error'),
});
};

return {
Expand Down
31 changes: 13 additions & 18 deletions packages/frontend/src/hooks/sign/in/use-sign-in-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,23 @@ export const useSignInView = () => {

const onSubmit = async (values: z.infer<typeof formSchema>) => {
setError('');
const mutation = await mutationApi(values);
if (!mutation?.message) return;
if (mutation.message === 'EMAIL_NOT_VERIFIED') {
setError('EMAIL_NOT_VERIFIED');

try {
await mutationApi(values);
} catch (e) {
const { message } = e as Error;
if (message === 'NEXT_REDIRECT') return;
if (message.includes('EMAIL_NOT_VERIFIED')) {
setError('EMAIL_NOT_VERIFIED');

return;
}

if (message.includes('ACCESS_DENIED')) {
setError('ACCESS_DENIED');
return;
}

return;
}
if (mutation.message === 'ACCESS_DENIED') {
setError('ACCESS_DENIED');

toast.error(t('title'), {
description: t('internal_server_error'),
});
return;
}

toast.error(t('title'), {
description: t('internal_server_error'),
});
};

return {
Expand Down
33 changes: 25 additions & 8 deletions packages/frontend/src/hooks/sign/up/mutation-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,29 @@ export const mutationApi = async (
token: string;
} & SignUpAuthBody,
) => {
await fetcher<{ email: string }, SignUpAuthBody>({
url: '/core/auth/sign_up',
method: 'POST',
body,
headers: {
'x-vitnode-captcha-token': body.token,
},
});
try {
await fetcher<{ email: string }, SignUpAuthBody>({
url: '/core/auth/sign_up',
method: 'POST',
body,
headers: {
'x-vitnode-captcha-token': body.token,
},
});
} catch (err) {
const { message } = err as Error;
if (message.includes('CAPTCHA_FAILED')) {
return { message: 'CAPTCHA_FAILED' };
}

if (message.includes('EMAIL_ALREADY_EXISTS')) {
return { message: 'EMAIL_ALREADY_EXISTS' };
}

if (message.includes('NAME_ALREADY_EXISTS')) {
return { message: 'NAME_ALREADY_EXISTS' };
}

return { message: 'INTERNAL_SERVER_ERROR' };
}
};
89 changes: 44 additions & 45 deletions packages/frontend/src/hooks/sign/up/use-sign-up-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,59 +62,58 @@ export const useSignUpView = () => {
return;
}

try {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { terms, ...rest } = values;
await mutationApi({
...rest,
token,
});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { terms, ...rest } = values;
const mutation = await mutationApi({
...rest,
token,
});
if (!mutation?.message) {
setEmailSuccess(values.email);
} catch (err) {
const { message } = err as Error;

if (message.includes('CAPTCHA_FAILED')) {
toast.error(tCore('errors.title'), {
description: tCore('errors.captcha_failed'),
});
return;
}

return;
}
if (mutation.message === 'CAPTCHA_FAILED') {
toast.error(tCore('errors.title'), {
description: tCore('errors.captcha_failed'),
});

if (message.includes('EMAIL_ALREADY_EXISTS')) {
form.setError(
'email',
{
type: 'manual',
message: t('email.already_exists'),
},
{
shouldFocus: true,
},
);
return;
}

return;
}
if (message.includes('NAME_ALREADY_EXISTS')) {
form.setError(
'name',
{
type: 'manual',
message: t('name.already_exists'),
},
{
shouldFocus: true,
},
);
if (mutation.message === 'EMAIL_ALREADY_EXISTS') {
form.setError(
'email',
{
type: 'manual',
message: t('email.already_exists'),
},
{
shouldFocus: true,
},
);

return;
}
return;
}
if (mutation.message === 'NAME_ALREADY_EXISTS') {
form.setError(
'name',
{
type: 'manual',
message: t('name.already_exists'),
},
{
shouldFocus: true,
},
);

toast.error(tCore('errors.title'), {
description: tCore('errors.internal_server_error'),
});
return;
}

toast.error(tCore('errors.title'), {
description: tCore('errors.internal_server_error'),
});
};

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,28 @@ export const mutationApi = async (
token: string;
} & SignUpAuthBody,
) => {
await fetcher<{ email: string }, SignUpAuthBody>({
url: '/core/auth/sign_up',
method: 'POST',
body,
headers: {
'x-vitnode-captcha-token': body.token,
},
});
try {
await fetcher<{ email: string }, SignUpAuthBody>({
url: '/core/auth/sign_up',
method: 'POST',
body,
headers: {
'x-vitnode-captcha-token': body.token,
},
});

revalidatePath('/[locale]/admin/(auth)/(vitnode)/members/users', 'page');
revalidatePath('/[locale]/admin/(auth)/(vitnode)/members/users', 'page');
} catch (err) {
const { message } = err as Error;

if (message.includes('EMAIL_ALREADY_EXISTS')) {
return { message: 'EMAIL_ALREADY_EXISTS' };
}

if (message.includes('NAME_ALREADY_EXISTS')) {
return { message: 'NAME_ALREADY_EXISTS' };
}

return { message: 'INTERNAL_SERVER_ERROR' };
}
};
Loading

0 comments on commit da811db

Please sign in to comment.