From 09645c620299ba39ebf02e383be61531274ab0d2 Mon Sep 17 00:00:00 2001 From: Elias Schneider Date: Thu, 28 Apr 2022 16:01:50 +0200 Subject: [PATCH] Improve error handling on upload --- .../upload/showCreateUploadModal.tsx | 19 +++-- src/pages/api/share/[shareId]/exists.ts | 19 +++++ src/pages/upload.tsx | 81 +++++++++++-------- src/services/share.service.ts | 19 +++-- 4 files changed, 86 insertions(+), 52 deletions(-) create mode 100644 src/pages/api/share/[shareId]/exists.ts diff --git a/src/components/upload/showCreateUploadModal.tsx b/src/components/upload/showCreateUploadModal.tsx index ddb3c148..b6e45c05 100644 --- a/src/components/upload/showCreateUploadModal.tsx +++ b/src/components/upload/showCreateUploadModal.tsx @@ -15,6 +15,7 @@ import { useForm, yupResolver } from "@mantine/form"; import { useModals } from "@mantine/modals"; import { ModalsContextProps } from "@mantine/modals/lib/context"; import * as yup from "yup"; +import shareService from "../../services/share.service"; const showCreateUploadModal = ( modals: ModalsContextProps, @@ -57,16 +58,20 @@ const Body = ({ return (
{ - modals.closeAll(); - uploadCallback(values.link, parseInt(values.expiration), { - password: values.password, - maxVisitors: values.maxVisitors, - }); + onSubmit={form.onSubmit(async (values) => { + if (await shareService.isIdAlreadyInUse(values.link)) { + form.setFieldError("link", "Link already in use."); + } else { + modals.closeAll(); + uploadCallback(values.link, parseInt(values.expiration), { + password: values.password, + maxVisitors: values.maxVisitors, + }); + } })} > - + { + const shareId = req.query.shareId as string; + let doesExists; + + try { + await awServer.database.getDocument("shares", shareId); + doesExists = true; + } catch { + doesExists = false; + } + + res.status(200).json({ exists: doesExists }); +}; + +export default handler; diff --git a/src/pages/upload.tsx b/src/pages/upload.tsx index 8d00652a..8e1069de 100644 --- a/src/pages/upload.tsx +++ b/src/pages/upload.tsx @@ -26,43 +26,54 @@ const Upload = () => { security: { password?: string; maxVisitors?: number } ) => { setisUploading(true); + try { + files.forEach((file) => { + file.uploadingState = "inProgress"; + }); - const bucketId = JSON.parse( - ( - await aw.functions.createExecution( - "createShare", - JSON.stringify({ id, security, expiration }), - false - ) - ).stdout - ).id; - for (let i = 0; i < files.length; i++) { - files[i].uploadingState = "inProgress"; - setFiles([...files]); - aw.storage.createFile(bucketId, "unique()", files[i]).then( - async () => { - files[i].uploadingState = "finished"; - setFiles([...files]); - if (!files.some((f) => f.uploadingState == "inProgress")) { - await aw.functions.createExecution( - "finishShare", - JSON.stringify({ id }), - false - ), - setisUploading(false); - showCompletedUploadModal( - modals, - `${window.location.origin}/share/${bucketId}`, - new Date(Date.now() + expiration * 60 * 1000).toLocaleString() - ); + const bucketId = JSON.parse( + ( + await aw.functions.createExecution( + "createShare", + JSON.stringify({ id, security, expiration }), + false + ) + ).stdout + ).id; + for (let i = 0; i < files.length; i++) { + setFiles([...files]); + aw.storage.createFile(bucketId, "unique()", files[i]).then( + async () => { + files[i].uploadingState = "finished"; + setFiles([...files]); + if (!files.some((f) => f.uploadingState == "inProgress")) { + await aw.functions.createExecution( + "finishShare", + JSON.stringify({ id }), + false + ), + setisUploading(false); + showCompletedUploadModal( + modals, + `${window.location.origin}/share/${bucketId}`, + new Date(Date.now() + expiration * 60 * 1000).toLocaleString() + ); + setFiles([]); + } + }, + (error) => { + files[i].uploadingState = undefined; + throw error; } - }, - (error) => { - files[i].uploadingState = undefined; - toast.error(error.message); - setisUploading(false); - } - ); + ); + } + } catch (e: any) { + setisUploading(false); + if (e.message) { + toast.error(e.message); + } else { + toast.error("An unknown error occurred."); + } } }; diff --git a/src/services/share.service.ts b/src/services/share.service.ts index 65ab7d77..f4f2a965 100644 --- a/src/services/share.service.ts +++ b/src/services/share.service.ts @@ -2,18 +2,17 @@ import axios from "axios"; import { AppwriteFileWithPreview } from "../types/File.type"; const get = async (shareId: string, password?: string) => { - return ( - await axios.post(`/api/share/${shareId}`, { password }) - ).data as AppwriteFileWithPreview[]; + return (await axios.post(`/api/share/${shareId}`, { password })) + .data as AppwriteFileWithPreview[]; +}; +const isIdAlreadyInUse = async (shareId: string) => { + return (await axios.get(`/api/share/${shareId}/exists`)).data + .exists as boolean; }; const authenticateWithPassword = async (shareId: string, password?: string) => { - return ( - await axios.post( - `/api/share/${shareId}/enterPassword`, - { password } - ) - ).data as AppwriteFileWithPreview[]; + return (await axios.post(`/api/share/${shareId}/enterPassword`, { password })) + .data as AppwriteFileWithPreview[]; }; -export default { get, authenticateWithPassword }; +export default { get, authenticateWithPassword, isIdAlreadyInUse };