diff --git a/frontend/src/pages/ClipEdit.tsx b/frontend/src/pages/ClipEdit.tsx index 35cf0eb..e43959f 100644 --- a/frontend/src/pages/ClipEdit.tsx +++ b/frontend/src/pages/ClipEdit.tsx @@ -33,18 +33,15 @@ const ClipEdit = () => { setDownloadable(false); - const edited = await editFile(id, outputMetadata); - const processed = await processFile(id); + const edited = await editFile(id, outputMetadata, setError); if (!edited) { - console.log("Failed to edit file"); - setError("Failed to edit file. Please check the metadata and try again."); return; } + const processed = await processFile(id, setError); + if (!processed) { - console.log("Failed to process file"); - setError("Failed to process file. Please try again later."); return; } diff --git a/frontend/src/pages/ClipUpload.tsx b/frontend/src/pages/ClipUpload.tsx index 192dd67..9743ed5 100644 --- a/frontend/src/pages/ClipUpload.tsx +++ b/frontend/src/pages/ClipUpload.tsx @@ -8,14 +8,14 @@ const clipUpload = () => { const [file, setFile] = useState(null); const navigate = useNavigate(); - const [noFileError, setNoFileError] = useState(false); + const [error, setError] = useState(null); const press = (() => { if (file) { - uploadFile(file) + uploadFile(file, setError) .then(uuid => navigate(`/create/${uuid}`)) .catch(e => console.error(e)); } else { - setNoFileError(true); + setError("Please choose a file"); } }); @@ -35,9 +35,7 @@ const clipUpload = () => { Upload - {noFileError && - - } + ) }; diff --git a/frontend/src/utils/endpoints.ts b/frontend/src/utils/endpoints.ts index 0ec3c92..a916dfc 100644 --- a/frontend/src/utils/endpoints.ts +++ b/frontend/src/utils/endpoints.ts @@ -1,9 +1,9 @@ -import type {VideoMetadata} from "./types.ts"; +import type {VideoMetadata, APIResponse} from "./types.ts"; /** * Uploads a file to the backend. */ -const uploadFile = async (file: File): Promise => { +const uploadFile = async (file: File, setError: Function): Promise => { const formData = new FormData(); formData.append('file', file); @@ -13,16 +13,15 @@ const uploadFile = async (file: File): Promise => { body: formData, }); - if (!response.ok) { - console.error('File upload failed with status:', response.status); - return ''; + const result: APIResponse = await response.json(); + + if (result.status == "error") { + setError(result.message); } - const result = await response.json(); - return result.data?.uuid ?? ''; + return result.data.uuid; } catch (error: unknown) { - console.error('Error uploading file:', error); - return ''; + throw new Error(`Failed to upload file: ${error instanceof Error ? error.message : 'Unknown error'}`); } }; @@ -31,8 +30,8 @@ const uploadFile = async (file: File): Promise => { */ const editFile = async ( uuid: string, - videoMetadata: VideoMetadata -): Promise => { + videoMetadata: VideoMetadata, + setError: Function ): Promise => { const formData = new URLSearchParams(); for (const [key, value] of Object.entries(videoMetadata)) { @@ -50,7 +49,14 @@ const editFile = async ( body: formData.toString(), }); - return response.ok; + const result: APIResponse = await response.json(); + + if (result.status === "error") { + setError(result.message); + return false; + } + + return true; } catch (error: unknown) { console.error('Error editing file:', error); return false; @@ -59,9 +65,16 @@ const editFile = async ( /** * Triggers file processing. */ -const processFile = async (uuid: string): Promise => { +const processFile = async (uuid: string, setError: Function): Promise => { try { const response = await fetch(`/api/v1/process/${uuid}`); + + const result: APIResponse = await response.json(); + if (result.status === "error") { + setError(result.message); + return false; + } + return response.ok; } catch (error: unknown) { console.error('Error processing file:', error); diff --git a/frontend/src/utils/types.ts b/frontend/src/utils/types.ts index 439c0ca..0572b48 100644 --- a/frontend/src/utils/types.ts +++ b/frontend/src/utils/types.ts @@ -7,6 +7,13 @@ type VideoMetadata = { fileSize: number } +type APIResponse = { + status: string, + data: any, + message: string +} + export type { + APIResponse, VideoMetadata } \ No newline at end of file diff --git a/src/main/java/com/ddf/vodsystem/controllers/GlobalExceptionHandler.java b/src/main/java/com/ddf/vodsystem/controllers/GlobalExceptionHandler.java index fddc064..dfedadf 100644 --- a/src/main/java/com/ddf/vodsystem/controllers/GlobalExceptionHandler.java +++ b/src/main/java/com/ddf/vodsystem/controllers/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.ddf.vodsystem.controllers; import com.ddf.vodsystem.entities.APIResponse; +import com.ddf.vodsystem.exceptions.FFMPEGException; import com.ddf.vodsystem.exceptions.JobNotFinished; import com.ddf.vodsystem.exceptions.JobNotFound; import org.springframework.http.HttpStatus; @@ -60,4 +61,11 @@ public class GlobalExceptionHandler { APIResponse response = new APIResponse<>(ERROR, ex.getMessage(), null); return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); } + + @ExceptionHandler(FFMPEGException.class) + public ResponseEntity> handleFFMPEGException(FFMPEGException ex) { + logger.error("FFMPEGException: {}", ex.getMessage(), ex); + APIResponse response = new APIResponse<>(ERROR, "FFMPEG Error: Please upload a valid file", null); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } } \ No newline at end of file