jueves, 9 de octubre de 2025

Obtener el mensaje de un error en Javascript

 ¿Cómo obtengo a partir de un error obtenido en un catch de una Promise los primeros 255 caracteres de su mensaje?

Es una excelente pregunta, ya que los objetos Error en JavaScript pueden tener distintos formatos (un simple string, un objeto con una propiedad message, etc.).

Para garantizar que siempre obtengas una cadena de texto y que esté limitada a los primeros 255 caracteres, te mostraré una función simple y robusta en JavaScript.

Generaré un archivo extract_error_message.js que contiene la función de utilidad y un ejemplo de su uso.

Extract Message from Error
/**
* Función de utilidad para extraer y truncar el mensaje de error.
*
* @param {any} error El objeto o valor recibido en el bloque 'catch' de una promesa.
* @returns {string} Los primeros 255 caracteres del mensaje de error, o un mensaje por defecto.
*/
function extractErrorMessage(error) {
let message = 'Error desconocido o no se pudo extraer el mensaje.';
const MAX_LENGTH = 255;

// 1. Manejar objetos Error estándar (y errores de red como Axios/Fetch)
if (error && typeof error === 'object') {
// La mayoría de los errores tienen una propiedad 'message'
if (error.message) {
message = String(error.message);
}
// Si el error es una respuesta de Fetch/Axios (que tiene un objeto de respuesta anidado)
else if (error.response && error.response.data && error.response.data.message) {
message = String(error.response.data.message);
}
// Fallback para errores serializados a JSON
else {
try {
// Intenta serializar el objeto completo para capturar cualquier detalle
message = JSON.stringify(error);
} catch (e) {
// Si la serialización falla (ej. referencias circulares)
message = 'Error en el objeto, imposible serializarlo.';
}
}
}
// 2. Manejar errores que son simplemente strings
else if (typeof error === 'string') {
message = error;
}
// 3. Truncar el mensaje a la longitud máxima
if (message.length > MAX_LENGTH) {
// Trunca y añade puntos suspensivos para indicar que fue cortado
return message.substring(0, MAX_LENGTH - 3) + '...';
}

return message;
}

// --- Ejemplo de Uso ---

// 1. Error estándar (Lanzado con new Error())
async function testCase1() {
try {
throw new Error('Este es un mensaje de error muy largo para probar la funcionalidad de truncamiento y ver si se corta correctamente a los 255 caracteres. Escribamos mucho más texto aquí para asegurarnos de que el corte funciona bien y que siempre obtenemos una salida manejable y limpia en nuestros logs o mensajes para el usuario. Esto ayuda a prevenir problemas de formato y sobrecarga de interfaz.');
} catch (err) {
console.log("--- Caso 1: Error Largo Estándar ---");
const shortMessage = extractErrorMessage(err);
console.log(`Mensaje Original (Longitud ${err.message.length}):`, err.message);
console.log(`Mensaje Truncado (Longitud ${shortMessage.length}):`, shortMessage);
console.log('-'.repeat(40));
}
}

// 2. Error que es solo un string (Lanzado con throw "string")
async function testCase2() {
try {
throw "Falló la autenticación del servidor. No es un objeto Error.";
} catch (err) {
console.log("--- Caso 2: Error tipo String ---");
const shortMessage = extractErrorMessage(err);
console.log(`Mensaje Original (Tipo: ${typeof err}):`, err);
console.log(`Mensaje Extraído:`, shortMessage);
console.log('-'.repeat(40));
}
}

// 3. Error sin propiedad 'message' (Objeto custom)
async function testCase3() {
try {
throw { code: 503, detail: "El servicio de procesamiento de imágenes no responde." };
} catch (err) {
console.log("--- Caso 3: Objeto sin 'message' ---");
const shortMessage = extractErrorMessage(err);
console.log(`Mensaje Original:`, err);
console.log(`Mensaje Extraído (JSON stringificado):`, shortMessage);
console.log('-'.repeat(40));
}
}

// 4. Error nulo o indefinido
async function testCase4() {
try {
throw null;
} catch (err) {
console.log("--- Caso 4: Error Nulo ---");
const shortMessage = extractErrorMessage(err);
console.log(`Mensaje Extraído:`, shortMessage);
console.log('-'.repeat(40));
}
}


// Ejecutar todos los casos de prueba
(async () => {
await testCase1();
await testCase2();
await testCase3();
await testCase4();
})();

Explicación de la Solución

La función extractErrorMessage(error) funciona de la siguiente manera:

  1. Verificación de Tipo: Primero comprueba si el error es un objeto y si tiene la propiedad estándar message. Si la tiene (que es lo más común), usa ese valor.

  2. Manejo de Respuestas de API: Incluye una comprobación para errores más complejos, como los devueltos por librerías como Axios (error.response.data.message), intentando acceder a la ruta más común para mensajes de error de servidor.

  3. Fallback a Serialización: Si el objeto existe pero no tiene la propiedad message, intenta usar JSON.stringify(error). Esto es útil cuando el error es un objeto simple con campos personalizados (como { code: 500, description: 'Algo falló' }).

  4. Manejo de Strings: Si el error capturado es directamente una cadena de texto (lo que ocurre si se lanza con throw "Mi Error"), usa esa cadena directamente.

  5. Truncamiento: Finalmente, la longitud del mensaje resultante se compara con MAX_LENGTH (255). Si es más largo, se trunca y se añaden ... al final, asegurando que el resultado nunca exceda el límite.

No hay comentarios: