refactor(storage.service): replace axios with fetch for data storage and retrieval, improve error handling, and enhance code clarity

This commit is contained in:
NicolasCantu 2025-12-02 00:53:53 +01:00
parent 8580070dc4
commit 355d5ea18d
2 changed files with 66 additions and 90 deletions

View File

@ -28,7 +28,6 @@
"vite-plugin-static-copy": "^1.0.6" "vite-plugin-static-copy": "^1.0.6"
}, },
"dependencies": { "dependencies": {
"axios": "^1.7.8",
"comlink": "^4.4.2", "comlink": "^4.4.2",
"jose": "^6.0.11", "jose": "^6.0.11",
"vite-plugin-wasm": "^3.3.0" "vite-plugin-wasm": "^3.3.0"

View File

@ -1,135 +1,112 @@
import axios, { AxiosResponse } from 'axios'; export async function storeData(
servers: string[],
export async function storeData(servers: string[], key: string, value: Blob, ttl: number | null): Promise<AxiosResponse | null> { key: string,
value: Blob,
ttl: number | null
): Promise<Response | null> {
for (const server of servers) { for (const server of servers) {
try { try {
// 1. On vérifie d'abord si la donnée existe en appelant le bon service // 1. Vérification d'existence (GET)
// On passe 'server' au lieu de 'url' pour que testData construise la bonne URL
const dataExists = await testData(server, key); const dataExists = await testData(server, key);
if (dataExists) { if (dataExists) {
console.log('Data already stored:', key); console.log("Data already stored:", key);
continue; continue;
} else { } else {
console.log('Data not stored for server, proceeding to POST:', key, server); console.log(
"Data not stored for server, proceeding to POST:",
key,
server
);
} }
// 2. Construction URL
// Construction de l'URL pour le POST (stockage)
// Cette partie était correcte
let url: string; let url: string;
if (server.startsWith('/')) { if (server.startsWith("/")) {
// Relative path
url = `${server}/store/${encodeURIComponent(key)}`; url = `${server}/store/${encodeURIComponent(key)}`;
if (ttl !== null) { if (ttl !== null) url += `?ttl=${ttl}`;
url += `?ttl=${ttl}`;
}
} else { } else {
// Absolute URL
const urlObj = new URL(`${server}/store/${encodeURIComponent(key)}`); const urlObj = new URL(`${server}/store/${encodeURIComponent(key)}`);
if (ttl !== null) { if (ttl !== null) urlObj.searchParams.append("ttl", ttl.toString());
urlObj.searchParams.append('ttl', ttl.toString());
}
url = urlObj.toString(); url = urlObj.toString();
} }
// La ligne ci-dessous a été supprimée car le test est fait au-dessus // 3. Envoi (POST) avec Fetch
// const testResponse = await testData(url, key); // <-- LIGNE BOGUÉE SUPPRIMÉE const response = await fetch(url, {
method: "POST",
// Send the encrypted data as the raw request body.
const response = await axios.post(url, value, { // Note: c'est bien un POST sur 'url'
headers: { headers: {
'Content-Type': 'application/octet-stream' "Content-Type": "application/octet-stream",
}, },
body: value,
}); });
console.log('Data stored successfully:', key);
if (response.status !== 200) { if (response.ok) {
console.error('Received response status', response.status); // Status 200-299
console.log("Data stored successfully:", key);
return response;
} else if (response.status === 409) {
// Conflit (déjà existant), on retourne null comme avant
return null;
} else {
console.error("Received response status", response.status);
continue; continue;
} }
return response;
} catch (error) { } catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 409) { console.error("Error storing data:", error);
return null; // 409 Conflict (Key already exists)
}
console.error('Error storing data:', error);
} }
} }
return null; return null;
} }
// Fonction retrieveData (inchangée, elle était correcte) export async function retrieveData(
export async function retrieveData(servers: string[], key: string): Promise<ArrayBuffer | null> { servers: string[],
key: string
): Promise<ArrayBuffer | null> {
for (const server of servers) { for (const server of servers) {
try { try {
const url = server.startsWith('/') const url = server.startsWith("/")
? `${server}/retrieve/${key}` ? `${server}/retrieve/${key}`
: new URL(`${server}/retrieve/${key}`).toString(); : new URL(`${server}/retrieve/${key}`).toString();
console.log('Retrieving data', key,' from:', url); console.log("Retrieving data", key, " from:", url);
const response = await axios.get(url, { const response = await fetch(url, { method: "GET" });
responseType: 'arraybuffer'
}); if (response.ok) {
// Transformation en ArrayBuffer
if (response.status === 200) { return await response.arrayBuffer();
if (response.data instanceof ArrayBuffer) {
return response.data;
} else {
console.error('Server returned non-ArrayBuffer data:', typeof response.data);
continue;
}
} else { } else {
console.error(`Server ${server} returned status ${response.status}`); if (response.status === 404) {
console.log(`Data not found on server ${server} for key ${key}`);
} else {
console.error(
`Server ${server} returned status ${response.status}: ${response.statusText}`
);
}
continue; continue;
} }
} catch (error) { } catch (error) {
if (axios.isAxiosError(error)) { console.error(`Unexpected error retrieving data from ${server}:`, error);
if (error.response?.status === 404) { continue;
// C'est normal si la donnée n'existe pas
console.log(`Data not found on server ${server} for key ${key}`);
continue;
} else if (error.response?.status) {
console.error(`Server ${server} error ${error.response.status}:`, error.response.statusText);
continue;
} else {
console.error(`Network error connecting to ${server}:`, error.message);
continue;
}
} else {
console.error(`Unexpected error retrieving data from ${server}:`, error);
continue;
}
} }
} }
return null; return null;
} }
interface TestResponse {
key: string;
value: boolean;
}
// Elle prend 'server' au lieu de 'url' et construit sa propre URL '/test/...'
export async function testData(server: string, key: string): Promise<boolean> { export async function testData(server: string, key: string): Promise<boolean> {
try { try {
// Construit l'URL /test/... const testUrl = server.startsWith("/")
const testUrl = server.startsWith('/')
? `${server}/test/${encodeURIComponent(key)}` ? `${server}/test/${encodeURIComponent(key)}`
: new URL(`${server}/test/${encodeURIComponent(key)}`).toString(); : new URL(`${server}/test/${encodeURIComponent(key)}`).toString();
const response = await axios.get(testUrl); // Fait un GET sur /test/... // On utilise fetch ici aussi
const response = await fetch(testUrl, { method: "GET" });
// 200 OK = la donnée existe
return response.status === 200;
// 200 OK = existe
return response.status === 200;
} catch (error) { } catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 404) { // Erreur réseau
// 404 Not Found = la donnée n'existe pas. C'est une réponse valide. console.error("Error testing data:", error);
return false; return false;
}
// Toute autre erreur (serveur offline, 500, etc.)
console.error('Error testing data:', error);
return false; // On considère que le test a échoué
} }
} }