No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Manejo de errores con throw y NotFoundException

16/23
Recursos

Desarrollar una API correctamente también implica manejar los errores que sus endpoints pueden tener de manera clara para el front-end.

Manejo de errores con NestJS

NestJS implementa de forma muy sencilla la posibilidad de responder con errores al cliente que realiza las consultas. Esto lo hace con una serie de clases que implementan los códigos HTTP correctos dependiendo el tipo de error que necesites.

import { NotFoundException } from '@nestjs/common';

@Get('product/:idProduct')
@HttpCode(HttpStatus.OK)
async getProduct(@Param('idProduct') idProduct: string): string {
  const product = await this.appService.getProducto(idProduct);
  if (!product) {
      throw new NotFoundException(`Producto con ID #${idProduct} no encontrado.`);
  }
  return product;
}

Importando NotFoundException puedes arrojar un error con la palabra reservada throw indicando que un registro no fue encontrado. Esta excepción cambiará el estado HTTP 200 que envía el decorador @HttpCode(HttpStatus.OK) por un 404 que es el correspondiente para la ocasión.

También puedes lanzar errores cuando el usuario no tiene permisos para acceder a un recurso.

import { ForbiddenException } from '@nestjs/common';

@Get('product/:idProduct')
@HttpCode(HttpStatus.OK)
async getProduct(@Param('idProduct') idProduct: string): string {
  // ...
  throw new ForbiddenException(`Acceso prohibido a este recurso.`);
}

O incluso lanzar errores de la familia del 5XX cuando ocurre un error inesperado en el servidor.

import { InternalServerErrorException } from '@nestjs/common';

@Get('product/:idProduct')
@HttpCode(HttpStatus.OK)
async getProduct(@Param('idProduct') idProduct: string): string {
  // ...
  throw new InternalServerErrorException(`Ha ocurrido un error inesperado.`);
}

Explora todas las clases con estados HTTP que NestJS posee para desarrollar tus endpoints de manera profesional y manejar correctamente los errores.

SRC services

// src/services/products.service.ts

import { ..., NotFoundException } from '@nestjs/common';

@Injectable()
export class ProductsService {
  ...

  findOne(id: number) {
    const product = this.products.find((item) => item.id === id);
    if (!product) {
      throw new NotFoundException(`Product #${id} not found`);
    }
    return product;
  }

  update(id: number, payload: any) {
    const product = this.findOne(id);
    const index = this.products.findIndex((item) => item.id === id);
    this.products[index] = {
      ...product,
      ...payload,
    };
    return this.products[index];
  }

  remove(id: number) {
    const index = this.products.findIndex((item) => item.id === id);
    if (index === -1) {
      throw new NotFoundException(`Product #${id} not found`);
    }
    this.products.splice(index, 1);
    return true;
  }
}
// src/controllers/products.controller.ts

  @Delete(':id')
  delete(@Param('id') id: string) {
    return this.productsService.remove(+id);
  }

Contribución creada por: Kevin Fiorentino.

Aportes 16

Preguntas 6

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Otra forma de manejar excepciones es con el modulo HttpException seria algo asi
aqui esta en la documentación

import { HttpException, HttpStatus } from '@nestjs/common';

// DENTRO DE TU SERVICIO O CONTROLLER
getProducts(){
    throw new HttpException('Error no se encontro', HttpStatus.BAD_REQUEST);
}

Como buena practica, los errores se pueden lanzar desde los proveedores o servicios, pero se deben atrapar en los controllers.
Con try catch

Un falso positivo xd

Un ejemplo con HttpException retornando un NOT_FOUND

<code> 
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Product } from 'src/entities/product.entity';

// SERVICE

    findOne(id: number) {
        const product = this.products.find(
            (item) => item.id === id
        );

        if (!product)
            throw new HttpException(
                'Product not found',
                HttpStatus.NOT_FOUND
            );

        return product
    }


	

No se totea ! jejeje
Me imagino que quiso decir que no rompe.

Ya que usa findOne() no veo pq volver a user findIndex. Se podria reescribir así:

update_(id: number, payload: any) {
    const product = this.findOne(id);
    const idx  = product.id;
    if (idx){
    this.products[idx] = {
      ...product,
      ...payload,
    };
      return this.products[idx];
    }
    return null;

<code>

Inicialmente no se elminaba el producto por la triple comparacion === pero luego de agregar ParseIntPipe al decorador Param funcionó correctamente

delete(@Param("productId", ParseIntPipe) productId: number) { //Code here }
No es mejor manejar los errores en el servicio? y desde el controlador hacer un return del servicio? Para que quede más limpio el controller y en el servicio toda la lógica con las excepciones, como por ejemplo un throw new NotFoundException o el error que sea
No es mejor manejar los errores en el servicio? y desde el controlador hacer un return del servicio? Para que quede más limpio el controller y en el servicio toda la lógica con las excepciones.
El problema de usar NotFoundException en el servicio es que el servicio pasa a ser un eslabón dependiente de nuestra REST API, lo ideal es desde el servicio se disparen errores específicos no de la API sino del servicio (personalizados) y luego en el controlador manejemos los errores de la REST API
Se puede manejar el error en una función aparte y donde se requiera validar si existe el producto, llamar a la función: ``validateIfProductExist(id: string) {    const product = this.products.find((product) => product.id === id);    if (!product) {      throw new NotFoundException({        status: HttpStatus.NOT_FOUND,        error: `The product with id: ${id} was not found`,     });    }  }`` `findOne(id: string) {    this.validateIfProductExist(id);    ` `const product = this.products.find((product) => product.id === id);    return product;  }`

creo que esto vendría siendo una desventaja de nest. Entiendo que cuando mando el error desde el servicio en la respuesta me aparece el código correcto. Pero en el controler sigo enviando en el HttpCode una respuesta positiva. La verdad me confunde un poco.
Hasta ahora me ha encantado nest, pero esto me parece un poco raro

Manejar error de eliminar un producto que no existe

implementación del servicio remove borrar un producto en el el controlador

NotFoundException manejo de errores en Nest JS

Manejo de error cuando en el servicio findOne no encuentra ninguno