Skip to main content
Version: Next

Estándar de manejo de errores


Objetivo

El objetivo de este estándar es poder tener coherencia a la hora de crear el código y enviar alertas de retroalimentación al usuario


Artefactos en los que aplica

  • Código de las historias de usuario de textiles:
    • Backend
    • Frontend

Convenciones generales

  • La mayoría de los errores se deberán manejar desde el backend en lugar desde el frontend directamente.
  • Los errores de validación pueden ser utilizados en el frontend para mostrar al usuario retroalimentación específica.
  • Los errores se manejarán desde el repositorio del backend.

Ejemplo frontend

Incorrecto ❌

Repositorio

export class RepositorioEjemplo {
static async crearEjemplo (parametros) {
try{
const respuesta = await axios.post(RUTAS_API.RUTA.EJEMPLO, {parametros})

return respuesta.data
}catch{
//El error no se esta manejando désde el backend
// Se esta manejando de manera en que el error siempre será el mismo
return "Error al crear el ejemplo"
}
}
}

Hook

const useCrearEjemplo = () => {
const crearEjemplo = async (parametros) => {
try{
const respuesta = await RepositorioCrearEjemplo.crearEjemplo(parametros)

const mensaje = respuesta.mensaje
return mensaje
}catch {
// El error esta siendo seteado de manera incorrecta
// Siempre será el mismo error
// Si hay un error inesperado o un error crítico no se podrá dar feedback
const mensaje = "Error al crear ejemplo"
return mensaje
}
}
}

Correcto ✅

Repositorio

export class RepositorioEjemplo {
static async crearEjemplo (parametros) {
try{
const respuesta = await axios.post(RUTAS_API.RUTA.EJEMPLO, {parametros})

return respuesta.data
}catch (error){
// El error esta siendo correctamente manejado en el frontend
// En el backend tendremos que considerar todos los casos posibles que darán diferentes errores
throw new Error(error.response.data.mensaje)
}
}
}

Hook

const useCrearEjemplo = () => {
const crearEjemplo = async (parametros) => {
try{
const respuesta = await RepositorioCrearEjemplo.crearEjemplo(parametros)

return respuesta.mensaje
}catch (error) {
// Utilizamos directamente el error de la respuesta del api
// Esto hace que tengamos que manejar todos los casos alternos posibles directamente desde el backend
return error.message
}
}
}

Ejemplo backend

Incorrecto ❌

Controlador

exports.crearEjemplo = async (req,res) => {
const parametros = req.body.parametros

if(!parametros) {
return res.status(400).json{mensaje: "No se enviaron los parámetros"}
}

if(!parametros.parametro1) {
return res.status(401).json{mensaje: "No se enviaron los parámetros"}
}

if(!parametros.parametro2) {
return res.status(404).json{mensaje: "No se enviaron los parámetros"}
}

try{
await repositorio.crearEjemplo(parametros)

return res.status(200).json({mensaje: Exito creando el ejemplo})
}catch{
return res.status(500).json({mensaje: Error creando ejemplo})
}
}

Repositorio

exports.crearEjemplo = async (parametros) => {
try{
await correrQuery(QUERY, [parametros])
}catch {
return "Error creando ejemplo"
}
}

Errores:

  • Se esta haciendo el manejo de datos no críticos en el controlador

    • El controlador solo funciona como puente para recibir la petición y enviar una respuesta
  • Se estan enviando códigos incorrectos de HTTP para los errores ej. el error status 500 significa que el servidor tiene un error.

    • El estatus 500, aunque puede significar un error en el servidor, este se refiere a un error del que el server no puede dar más información, ya sea un bug o algo parecido
    • Si queremos dar a entender que hubo un error debido a lógica de negocio, como que el usuario ya exista, o que el nombre ya exista, es mejor enviar errores 4xx
  • En el repositorio no se estan haciendo validaciones, solo se esta llamando a la base de datos, lo que puede hacer que en historias más grandes que tengan muchos datos no se hagan buenas validaciones.

Como saber que estatus HTTP usar?

Pueden dirigirse a esta página, la cual contiene todos los estados utilizando imagenes de gatitos

HTTP CATS

Correcto ✅

Controlador

exports.crearEjemplo = async (req,res) => {
const parametros = req.body.parametros
const idCliente = req.user.clienteSeleccionado

// Aqui tenemos validaciones críticas, ya que si no seleccionamos cliente no deberíamos hacer nada más
// Si los parametros no fueron enviados solo estaremos esperando errores más adelante, es mejor retornarlo lo más rápido posible
if(!idCliente) {
return res.status(400).json({mensaje: "Cliente no seleccionado"})
}
if(!parametros) {
return res.status(400).json({mensaje: "Parametros no fueron enviados"})
}

try{
await repositorio.crearEjemplo(parametros, idCliente)

return res.status(200).json({mensaje: "Se creo el ejemplo exitosamente"})
}catch (error){
// A pesar de que el estandar departamental es español, .message es una propiedad reservada de los errores
return res.status(400).json({mensaje: error.message})
}
}

Repositorio

exports.crearEjemplo = async (parametros, idCliente) => {

if(parametros.parametro1 >= 0){
throw new Error("El parametro 1 debe ser 0")
}

if(!parametros.parametro2 || typeof parametros.parametro2 !== "Number" ) {
throw new Error("El parametro 2 es obligatorio y tiene que ser numerico")
}

try {
const respuesta = await correrQuery(QUERY,[parametros, idCliente])

if(respuesta.insertId !== 0){
throw new Error("No se creo el ejemplo")
}

return
}catch (error){
throw new Error(error.message)
}
}

Que se hizo bien?

  • Se estan manejando 2 diferentes errores de reglas de negocio en el repositorio

  • Se estan manejando 1 error en el que se especifica que no se creo el ejemplo, este puede ser inesperado o otro tipo de error, eso depende de lo que se identifico en el analisis

  • Por último, se maneja el error en caso de que haya habido algun error al correr la query, este es el último error posible, y el que esperamos que no se retorne ya que ya se deberían haber hecho las validaciones necesarias

  • El controlador enviara 4 diferentes mensajes de error en diferentes casos, en lugar de 1 solo error no descriptivo


Que conseguimos con esto

Es más limpio, más ordenado, y más facil de leer los errores que estamos obteniendo si se envian desde el backend, tambien hace que nuestro código en el frontend no tenga tantas validaciones, y nos podamos concentrar en la logica de reenderizacion y manejo de datos.


Historial de versiones

Tipo de VersiónDescripciónFechaColaborador
1.0Crear el estándar de manejo de errores4/06/2025Diego Alfaro