IMPROVE error handling on frontend

This commit is contained in:
2025-06-10 12:12:19 +02:00
parent faaac0abec
commit f79beadb09
5 changed files with 48 additions and 25 deletions

View File

@@ -33,18 +33,15 @@ const ClipEdit = () => {
setDownloadable(false); setDownloadable(false);
const edited = await editFile(id, outputMetadata); const edited = await editFile(id, outputMetadata, setError);
const processed = await processFile(id);
if (!edited) { if (!edited) {
console.log("Failed to edit file");
setError("Failed to edit file. Please check the metadata and try again.");
return; return;
} }
const processed = await processFile(id, setError);
if (!processed) { if (!processed) {
console.log("Failed to process file");
setError("Failed to process file. Please try again later.");
return; return;
} }

View File

@@ -8,14 +8,14 @@ const clipUpload = () => {
const [file, setFile] = useState<File | null>(null); const [file, setFile] = useState<File | null>(null);
const navigate = useNavigate(); const navigate = useNavigate();
const [noFileError, setNoFileError] = useState(false); const [error, setError] = useState<null | string>(null);
const press = (() => { const press = (() => {
if (file) { if (file) {
uploadFile(file) uploadFile(file, setError)
.then(uuid => navigate(`/create/${uuid}`)) .then(uuid => navigate(`/create/${uuid}`))
.catch(e => console.error(e)); .catch(e => console.error(e));
} else { } else {
setNoFileError(true); setError("Please choose a file");
} }
}); });
@@ -35,9 +35,7 @@ const clipUpload = () => {
Upload Upload
</BlueButton> </BlueButton>
{noFileError && <label className={"text-center text-red-500"}>{error}</label>
<label className={"text-center text-red-500"}>Please choose a file</label>
}
</Box> </Box>
) )
}; };

View File

@@ -1,9 +1,9 @@
import type {VideoMetadata} from "./types.ts"; import type {VideoMetadata, APIResponse} from "./types.ts";
/** /**
* Uploads a file to the backend. * Uploads a file to the backend.
*/ */
const uploadFile = async (file: File): Promise<string> => { const uploadFile = async (file: File, setError: Function): Promise<string> => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', file);
@@ -13,16 +13,15 @@ const uploadFile = async (file: File): Promise<string> => {
body: formData, body: formData,
}); });
if (!response.ok) { const result: APIResponse = await response.json();
console.error('File upload failed with status:', response.status);
return ''; if (result.status == "error") {
setError(result.message);
} }
const result = await response.json(); return result.data.uuid;
return result.data?.uuid ?? '';
} catch (error: unknown) { } catch (error: unknown) {
console.error('Error uploading file:', error); throw new Error(`Failed to upload file: ${error instanceof Error ? error.message : 'Unknown error'}`);
return '';
} }
}; };
@@ -31,8 +30,8 @@ const uploadFile = async (file: File): Promise<string> => {
*/ */
const editFile = async ( const editFile = async (
uuid: string, uuid: string,
videoMetadata: VideoMetadata videoMetadata: VideoMetadata,
): Promise<boolean> => { setError: Function ): Promise<boolean> => {
const formData = new URLSearchParams(); const formData = new URLSearchParams();
for (const [key, value] of Object.entries(videoMetadata)) { for (const [key, value] of Object.entries(videoMetadata)) {
@@ -50,7 +49,14 @@ const editFile = async (
body: formData.toString(), 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) { } catch (error: unknown) {
console.error('Error editing file:', error); console.error('Error editing file:', error);
return false; return false;
@@ -59,9 +65,16 @@ const editFile = async (
/** /**
* Triggers file processing. * Triggers file processing.
*/ */
const processFile = async (uuid: string): Promise<boolean> => { const processFile = async (uuid: string, setError: Function): Promise<boolean> => {
try { try {
const response = await fetch(`/api/v1/process/${uuid}`); 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; return response.ok;
} catch (error: unknown) { } catch (error: unknown) {
console.error('Error processing file:', error); console.error('Error processing file:', error);

View File

@@ -7,6 +7,13 @@ type VideoMetadata = {
fileSize: number fileSize: number
} }
type APIResponse = {
status: string,
data: any,
message: string
}
export type { export type {
APIResponse,
VideoMetadata VideoMetadata
} }

View File

@@ -1,6 +1,7 @@
package com.ddf.vodsystem.controllers; package com.ddf.vodsystem.controllers;
import com.ddf.vodsystem.entities.APIResponse; import com.ddf.vodsystem.entities.APIResponse;
import com.ddf.vodsystem.exceptions.FFMPEGException;
import com.ddf.vodsystem.exceptions.JobNotFinished; import com.ddf.vodsystem.exceptions.JobNotFinished;
import com.ddf.vodsystem.exceptions.JobNotFound; import com.ddf.vodsystem.exceptions.JobNotFound;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@@ -60,4 +61,11 @@ public class GlobalExceptionHandler {
APIResponse<Void> response = new APIResponse<>(ERROR, ex.getMessage(), null); APIResponse<Void> response = new APIResponse<>(ERROR, ex.getMessage(), null);
return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); return ResponseEntity.status(HttpStatus.ACCEPTED).body(response);
} }
@ExceptionHandler(FFMPEGException.class)
public ResponseEntity<APIResponse<Void>> handleFFMPEGException(FFMPEGException ex) {
logger.error("FFMPEGException: {}", ex.getMessage(), ex);
APIResponse<Void> response = new APIResponse<>(ERROR, "FFMPEG Error: Please upload a valid file", null);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
}
} }