From 66231f9b7cdb2ab28e69a1b971af2e784e8a3119 Mon Sep 17 00:00:00 2001 From: Alexis Date: Tue, 14 Apr 2026 12:02:43 +0200 Subject: [PATCH] fix: mejorar manejo de errores en funciones de servicio y respuesta de API --- frontend/src/lib/api.js | 22 +++++++++++ frontend/src/pages/DocEditor.jsx | 61 +++++++++-------------------- frontend/src/services/docService.js | 22 +++++------ 3 files changed, 51 insertions(+), 54 deletions(-) diff --git a/frontend/src/lib/api.js b/frontend/src/lib/api.js index 787616f..1cabe5d 100644 --- a/frontend/src/lib/api.js +++ b/frontend/src/lib/api.js @@ -17,4 +17,26 @@ api.interceptors.request.use((config) => { return config; }); +api.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + if (error.response && error.response.status === 401) { + localStorage.removeItem('token'); + localStorage.removeItem('user'); + window.location.href = '/login'; + } + + if (error.response && error.response.data) { + return Promise.reject({ + ...error, + backendData: error.response.data + }); + } + + return Promise.reject(error); + } +); + export default api; \ No newline at end of file diff --git a/frontend/src/pages/DocEditor.jsx b/frontend/src/pages/DocEditor.jsx index edeb2ba..370ad1e 100644 --- a/frontend/src/pages/DocEditor.jsx +++ b/frontend/src/pages/DocEditor.jsx @@ -162,53 +162,28 @@ export default function DocEditor() { setFinalResult(result); setStep(3); } catch (error) { - console.error("Error capturado detallado:", error); - let friendlyMessage = "Ocurrió un error de validación al generar la gráfica."; - // 1. BUSCADOR DE ERRORES: Extraemos el detalle venga como venga (Axios, Pydantic, o genérico) - let details = error; - if (error.response && error.response.data && error.response.data.detail) { - details = error.response.data.detail; // Array de Pydantic - } else if (error.detail) { - details = error.detail; - } + let friendlyMessage = "Ocurrió un error al procesar la solicitud."; + const errorData = error.backendData || error.response?.data || error; - // 2. Si logramos extraer el Array de Pydantic - if (Array.isArray(details)) { - friendlyMessage = details.map(err => { - // Limpiamos el texto que ensucia Pydantic ("Value error, ") - const cleanMsg = err.msg ? err.msg.replace("Value error, ", "") : "Valor incorrecto"; - - // Buscamos en qué etiqueta falló usando err.loc - if (err.loc) { - const levelIndexPos = err.loc.indexOf("levels"); - if (levelIndexPos !== -1 && err.loc.length > levelIndexPos + 1) { - const levelIndex = err.loc[levelIndexPos + 1]; - const termName = scaleKeys[levelIndex] || `Nivel ${Number(levelIndex) + 1}`; - return `• En la etiqueta "${termName}": ${cleanMsg}`; - } - // Formato alternativo de Pydantic v2 - if (typeof err.loc[1] === 'number') { - const termName = scaleKeys[err.loc[1]] || `Nivel ${err.loc[1] + 1}`; - return `• En la etiqueta "${termName}": ${cleanMsg}`; - } + if (errorData.detail) { + if (errorData.detail === "Invalid input data") { + friendlyMessage = "Revisa los valores del Soporte y Núcleo. Asegúrate de que el 'Inicio del Soporte' sea menor o igual al 'Fin del Soporte', y que el 'Núcleo' esté dentro del 'Soporte'."; + } else if (typeof errorData.detail === 'string') { + friendlyMessage = errorData.detail; } - return `• ${cleanMsg}`; - }).join("\n"); - } - // 3. Si el backend nos mandó un simple string - else if (typeof details === 'string') { - friendlyMessage = details; - } - // 4. Si es un error genérico (Axios de bajo nivel) - else if (error.message) { - if (error.message.includes("422")) { - friendlyMessage = "Revisa los datos: asegúrate de que el 'Núcleo' esté dentro del 'Soporte' y que c <= d."; - } else { - friendlyMessage = error.message; - } + } else if (errorData.errors && Array.isArray(errorData.errors) && errorData.errors.length > 0) { + friendlyMessage = errorData.errors.map(err => { + let cleanMsg = err.msg ? err.msg.replace("Value error, ", "") : "Valor incorrecto"; + if (err.loc && err.loc.includes("levels")) { + const levelIndex = err.loc[err.loc.indexOf("levels") + 1]; + const termName = scaleKeys[levelIndex] || `Nivel ${Number(levelIndex) + 1}`; + return `• En la etiqueta "${termName}": ${cleanMsg}`; + } + return `• ${cleanMsg}`; + }).join("\n"); } - + setSubmitError(friendlyMessage); } finally { setIsLoading(false); diff --git a/frontend/src/services/docService.js b/frontend/src/services/docService.js index ecf3686..56f9b66 100644 --- a/frontend/src/services/docService.js +++ b/frontend/src/services/docService.js @@ -5,8 +5,8 @@ export const calculateValueFunction = async (payload) => { const response = await api.post('/criteria/doc/value-function', payload); return response.data; } catch (error) { - console.error('Error calculating value function:', error); - throw error.response?.data?.detail || error.message; + if (error.response && error.response.data) throw error.response.data; + throw error; } }; @@ -15,8 +15,8 @@ export const buildFuzzyGraph = async (payload) => { const response = await api.post('/criteria/doc-it2mf/build', payload); return response.data; } catch (error) { - console.error('Error building fuzzy graph:', error); - throw error.response?.data?.detail || error.message; + if (error.response && error.response.data) throw error.response.data; + throw error; } }; @@ -25,8 +25,8 @@ export const saveToHistory = async (payload) => { const response = await api.post('/history/add', payload); return response.data; } catch (error) { - console.error('Error saving to history:', error); - throw error.response?.data?.detail || error.message; + if (error.response && error.response.data) throw error.response.data; + throw error; } }; @@ -35,17 +35,17 @@ export const getUserHistory = async () => { const response = await api.get('/history/user'); return response.data; } catch (error) { - console.error('Error fetching history:', error); - throw error.response?.data?.detail || error.message; + if (error.response && error.response.data) throw error.response.data; + throw error; } }; export const deleteHistoryItem = async (id) => { try { - const response = await api.delete(`/history/delete/${id}`); + const response = await api.delete(`/history/${id}`); return response.data; } catch (error) { - console.error('Error deleting history item:', error); - throw error.response?.data?.detail || error.message; + if (error.response && error.response.data) throw error.response.data; + throw error; } }; \ No newline at end of file