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çã

Executar uma tarefa em background no Android usando React Native

Pegue um café e se ajeite na cadeira, pois vou contar uma história um pouco longa a respeito de como executar serviços em segundo plano com React-Native e imagino que vai servir mais como um norte na hora de desenvolver esse tipo de funcionalidade. Primeiro, pesquisei na documentação oficial do React, e lá é indicado um recurso chamado Headless JS, que permite criar uma ponte entre o JS e o código nativo, e executar tarefas em background. Em seguida, fiz uma pesquisa sobre como funcionam as tarefas em segundo plano no Android para entender quais são as possibilidades e prós e contras de cada abordagem. Sobre as abordagens, temos: # WorkManager A API WorkManager facilita a programação de tarefas adiáveis e assíncronas que precisam ser executadas mesmo se o app fechar ou o dispositivo reiniciar. Principais recursos: Compatível com versões anteriores até a API 14 Usa o JobScheduler em dispositivos com a API 23 ou posteriores Usa uma combinação de BroadcastReceiver + AlarmManage