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"
},
"dependencies": {
"axios": "^1.7.8",
"comlink": "^4.4.2",
"jose": "^6.0.11",
"vite-plugin-wasm": "^3.3.0"

View File

@ -1,135 +1,112 @@
import axios, { AxiosResponse } from 'axios';
export async function storeData(servers: string[], key: string, value: Blob, ttl: number | null): Promise<AxiosResponse | null> {
export async function storeData(
servers: string[],
key: string,
value: Blob,
ttl: number | null
): Promise<Response | null> {
for (const server of servers) {
try {
// 1. On vérifie d'abord si la donnée existe en appelant le bon service
// On passe 'server' au lieu de 'url' pour que testData construise la bonne URL
// 1. Vérification d'existence (GET)
const dataExists = await testData(server, key);
if (dataExists) {
console.log('Data already stored:', key);
console.log("Data already stored:", key);
continue;
} 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
);
}
// Construction de l'URL pour le POST (stockage)
// Cette partie était correcte
// 2. Construction URL
let url: string;
if (server.startsWith('/')) {
// Relative path
if (server.startsWith("/")) {
url = `${server}/store/${encodeURIComponent(key)}`;
if (ttl !== null) {
url += `?ttl=${ttl}`;
}
if (ttl !== null) url += `?ttl=${ttl}`;
} else {
// Absolute URL
const urlObj = new URL(`${server}/store/${encodeURIComponent(key)}`);
if (ttl !== null) {
urlObj.searchParams.append('ttl', ttl.toString());
}
if (ttl !== null) urlObj.searchParams.append("ttl", ttl.toString());
url = urlObj.toString();
}
// La ligne ci-dessous a été supprimée car le test est fait au-dessus
// const testResponse = await testData(url, key); // <-- LIGNE BOGUÉE SUPPRIMÉE
// Send the encrypted data as the raw request body.
const response = await axios.post(url, value, { // Note: c'est bien un POST sur 'url'
// 3. Envoi (POST) avec Fetch
const response = await fetch(url, {
method: "POST",
headers: {
'Content-Type': 'application/octet-stream'
"Content-Type": "application/octet-stream",
},
body: value,
});
console.log('Data stored successfully:', key);
if (response.status !== 200) {
console.error('Received response status', response.status);
if (response.ok) {
// 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;
}
return response;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 409) {
return null; // 409 Conflict (Key already exists)
}
console.error('Error storing data:', error);
console.error("Error storing data:", error);
}
}
return null;
}
// Fonction retrieveData (inchangée, elle était correcte)
export async function retrieveData(servers: string[], key: string): Promise<ArrayBuffer | null> {
export async function retrieveData(
servers: string[],
key: string
): Promise<ArrayBuffer | null> {
for (const server of servers) {
try {
const url = server.startsWith('/')
const url = server.startsWith("/")
? `${server}/retrieve/${key}`
: 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, {
responseType: 'arraybuffer'
});
const response = await fetch(url, { method: "GET" });
if (response.status === 200) {
if (response.data instanceof ArrayBuffer) {
return response.data;
if (response.ok) {
// Transformation en ArrayBuffer
return await response.arrayBuffer();
} else {
console.error('Server returned non-ArrayBuffer data:', typeof response.data);
continue;
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}`
);
}
} else {
console.error(`Server ${server} returned status ${response.status}`);
continue;
}
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.status === 404) {
// 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;
}
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> {
try {
// Construit l'URL /test/...
const testUrl = server.startsWith('/')
const testUrl = server.startsWith("/")
? `${server}/test/${encodeURIComponent(key)}`
: 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
// 200 OK = existe
return response.status === 200;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 404) {
// 404 Not Found = la donnée n'existe pas. C'est une réponse valide.
// Erreur réseau
console.error("Error testing data:", error);
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é
}
}