Pular para o conteúdo principal

Prefira exceções à códigos de erros #FastTip #CleanCode

Gostaria de compartilhar com vocês uma técnica que aprendi a me acostumar ao longo dos anos, mas que conheci pelo livro do Robert C. Martin, o Clean Code. De forma bem sintetizada, o autor relata que uma boa prática é retornar exceções, ao invés de códigos de erro, pois isso evita a escrita de códigos de verificação, e mantém ele enxuto, mais confiável, sem aberturas para bugs relacionados à erros não previstos. Esse conteúdo você encontrará no capítulo 3 (página 46 - 47) e no capítulo 7 (página 103 - 112), do livro supracitado.

Aí como exemplo, desenvolvi um pequeno código Javascript que pode servir de referência para os demais, por ser simples de entender.


// -----------------------------
// Criei uma classe genérica que permite acesso ao objeto
// Error, padrão do JS, e escrevo a stack trace nomeada
// à partir de um Error genérico
class GenericError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = {
  GenericError,
};

// -----------------------------

// Aqui é feita a especialização do erro.
// Nesse caso, será uma exceção para indicar CPF inválido

const { GenericError } = require('./GenericError');

class InvalidCPFError extends GenericError {
  constructor(cpf) {
    super(`O CPF ${cpf} não é válido.`);
    this.data = { cpf };
  }
} 

module.exports = {
  InvalidCPFError,
};

// -----------------------------

// Construí uma classe que utiliza o lançamento de exceção
// especializada 

const { InvalidCPFError } = require('../errors/InvalidCPFError');

module.exports = function validarCPF(cpf) {  
  cpf = cpf.replace(/[^\d]+/g, '');
  if (cpf == '') throw new InvalidCPFError(cpf);
  // Vamos supor que daqui pra baixo tenham outras
  // regras de validação
};

// -----------------------------

// Apenas na função que utiliza a função de validação
// é inserido um try-catch, que já abstraído o tipo
// retorna uma mensagem de erro padronizada
// sem que Eu me precise me preocupar com sua implementação
 

const validateCPF = require('../utils/validateCPF');

module.exports = {
  async store(request, response) {
    let { name, email, password, cpf, state, city } = request.body;
    try {
      validateCPF(cpf);
      // Vamos supor que daqui em diante, seja desenvolvido
      // o restante do código
    } catch (error) {
      return response.status(400).json({ error: error.message });
    }
  },
};
 
--------------------------------------------------------


Vale ressaltar que essa foi a abordagem de extração do bloco try-catch que melhor atendeu neste contexto proposto, mas um caminho mais ideal é ter uma função que apenas tem um único objetivo: abstrair o tratamento da exceção.

Tenha em mente que sempre será necessário olhar pro contexto, e o ideal é sempre aquela abordagem que dará menos trabalho e efeitos colaterais se precisar ser alterada, ou substituída no futuro.

Comentários

Postagens mais visitadas deste blog

Como serializar todos os dados de um formulário em um objeto JSON usando jQuery? #fastTip

Um dos pilares de um código bem escrito é: DRY (Dont Repeat Yourself - não se repita). Acontece que muitas vezes nos deparamos com situações que por conta da necessidade de entrega expressa (famoso código miojo - feito em 2 minutos), acabamos deixando de aplicar boas práticas. O que difere um amador de um profissional é a sua capacidade de avaliar o impacto que um código mal escrito causa e identificar os caminhos pra resolver esses impasses. Enfim, vamos ao que interessa: O Problema Desejo criar um objeto JSON à partir de um formulário, para ser enviado em uma requisição assíncrona. Atualmente, o objeto é criado assim: var data = { name: $('input[name="name"]').val(), email: $('input[name="email"]').val(), }; Olhando pra esse código, vemos diversos problemas: Se mudar o name do input, precisará ir lá no código para alterar a atribuição. Se houver um formulário com 20 campos, terá que fazer 20 atribuições, e assim por diante. A Soluçã...

Desenvolvendo um mapa usando ReactJS, MongoDB e um pouquinho de Redux - Parte 1 #BoraCodar

Sou um entusiasta desse negócio de transformar minhas ideias em código e ainda mais, quando isso me traz alguns bônus como: Aprender algo novo; contribuir com a comunidade; ou qualquer outra coisa que envolva sair da rotina. Sem mais delongas, dias atrás após conversar com alguns amigos do laboratório de computação da UEL (Universidade Estadual de Londrina), percebi que muita gente sai do ensino médio sem uma noção de quais cursos interessantes existem perto de onde mora, ou pior, aonde ela poderia encontrar aquele curso que mais se encaixa em seu perfil. Eu mesmo, antes de ir pra computação fiz 2 vestibulares na área de humanas (História e Ciências Sociais - ambas na Unesp) e um em computação (Fema - Assis, SP). Contudo,  quando saiu a nota do Enem vi que havia uma universidade próximo da minha cidade que era federal que que aceitava o programa Sisu. Foi assim que ingressei na UTFPR de Cornélio Procópio. Essa odisseia toda, me fez refletir que seria interessante usar meu tem...