Dev Doido.

Criando LogController e LogRepository para geração de logs de erro CrazyStack Node.js

Gustavo Miranda
Gustavo Miranda
- ... visualizações

Nesta aula, vamos criar dois novos componentes na nossa arquitetura de aplicação, o LogController e o LogRepository, responsáveis por gerar logs de erros em nossa API.

O LogController será uma classe extendida da nossa classe abstrata Controller, e será responsável por receber as informações de erro e enviá-las para o LogRepository para serem registradas.

Já o LogRepository será responsável por armazenar os logs de erro de forma persistente, seja em um banco de dados relacional, arquivo ou qualquer outra forma de armazenamento.

Esses componentes serão importantes para garantir a qualidade e a segurança da nossa aplicação, já que os logs de erro nos permitirão identificar e corrigir rapidamente possíveis falhas ou problemas. Além disso, a classe abstrata Controller nos permite ter uma implementação padronizada e genérica para todos os nossos controladores, o que facilita a manutenção e o desenvolvimento da aplicação.

Em resumo, a criação de um LogController e um LogRepository é uma boa prática para garantir a qualidade e a segurança da nossa API, e a utilização da classe abstrata Controller é uma forma de garantir a padronização e a facilidade na manutenção da nossa aplicação.

Este artigo servirá como uma espécie de documentação de alguns códigos vistos durante as aulas apenas como material complementar.

export interface LogRepository {
  logError(domain: string, stack: string): Promise<void>;
}

Essa é uma interface que define o comportamento esperado de um repositório de logs de erro. Ela contém um método, logError(domain: string, stack: string), que aceita dois parâmetros: domain (um string que representa o domínio onde o erro ocorreu) e stack (um string que representa a pilha de chamadas que causou o erro). O método retorna uma Promise que, quando resolvida, indica que o log de erro foi registrado com sucesso. Esta interface é utilizada para garantir que todas as implementações de repositórios de log tenham a mesma funcionalidade básica.

import { MongoHelper } from "@/application/infra";
import { LogRepository } from "@/application/infra/contracts";

export class LogMongoRepository implements LogRepository {
  async logError(domain: string, stack: string): Promise<void> {
    const errorCollection = await MongoHelper.getCollection("errors");
    await errorCollection.insertOne({ domain, stack, date: new Date() });
  }
}

Este código representa uma implementação da interface LogRepository usando MongoDB como base de dados. A classe LogMongoRepository implementa o método logError que salva um log de erro em uma coleção "errors".

O método logError recebe como parâmetros o nome do domínio onde o erro ocorreu e a pilha de erro (stack). Em seguida, usa a classe MongoHelper para obter uma instância da coleção "errors" no MongoDB. Por fim, insere um novo documento na coleção com as informações do erro (domínio, pilha e data atual).

import { Controller, LogRepository } from "@/application/infra/contracts";
import { HttpRequest, HttpResponse } from "../helpers";
export class LogController implements Controller {
  constructor(
    private readonly domain: string,
    private readonly controller: Controller,
    private readonly logRepository: LogRepository
  ) {}
  execute(httpRequest: HttpRequest<any>): Promise<HttpResponse<any>> {
    return this.controller.execute(httpRequest);
  }
  async handle(httpRequest: HttpRequest<any>): Promise<HttpResponse<any>> {
    const httpResponse = await this.execute(httpRequest);
    if (httpResponse?.statusCode === 500) {
      await this.logRepository.logError(this.domain, httpResponse?.data);
    }
    return httpResponse;
  }
}

Este é o código de uma classe de controlador de log, que implementa a interface Controller e utiliza a interface LogRepository para armazenar informações sobre erros ocorridos em sua execução. Ele funciona como uma camada de logging de erro adicional que registra erros específicos para o domínio que representa.

A classe tem uma construção que recebe três parâmetros:

  • domain: representa o domínio específico para o qual o log está sendo gerado.
  • controller: é um controlador que será envolta pelo controlador de log.
  • logRepository: é uma instância da classe LogRepository, responsável por armazenar os dados de log de erro.

A classe possui dois métodos:

  • execute: é uma delegação para o método execute do controlador que está sendo envolta.
  • handle: é o método principal da classe, responsável por capturar a resposta HTTP do controlador e verificar se o código de status é 500. Se for, ele utiliza o método logError do logRepository para armazenar os dados de erro no banco de dados. Em seguida, retorna a resposta HTTP para o controlador original.

LINK DO REPOSITÓRIO