caminhos infelizes - Quando usamos esse mecanismo em cenários em que podemos nos recuperar da falha, chamamos de um cenário de erro - Nessa talk focaremos em erros recuperáveis: - Erros de validação - Erros de autenticação - Erros de pagamento - …
Exception é muito genérica, mesmo que "só pra garantir" - Não devemos tratar erros para estados que são inerentemente inválidos e/ou que não podemos fazer nada a respeito - Tentar se recuperar de Exception sem uma razão muito boa torna seu código menos seguro
Esse é o erro: arquivo_com_erro_de_sintaxe.rb:3: syntax error, unexpected end-of-input, expecting `end' or dummy end Hierarquia de classes de erro em Ruby
- Erros e o método raise não devem ser usados onde uma condicional seria o suficiente - Isso seria semelhante a usar erros como: - Alternativas inadequadas para efeitos algébricos - Uma ação de goto - Fazer isso torna seu código mais difícil de ler e menos performático
erros - Tornar os cenários de erro explícitos - Prover informações o suficiente para o call-site (o lado que chama o código que pode falhar) tomar decisões - Seguir convenções e o Rails-way
descubra eles - Antes de escrever o código, projete ele considerando os caminhos infelizes do seu fluxo - Erros existem para se comunicar com o call-site - Só trate cenários que você pode se recuperar de maneira adequada
erro que expressam o que aconteceu - Especialmente importante quando: - Um método pode falhar por mais de um motivo, ou - Você precisa adicionar mais informação sobre o erro além da mensagem - Classes de erro customizadas devem ser herdar de StandardError - Adicione métodos à essas classes para enriquecer as informações
- Evite vazamento de abstrações erros - Do inglês "leaky abstraction" - A origem de um erro deve ser clara no call-site - Encapsule erros específicos de gems - Use o método Error#cause
vezes, precisamos tratar uma família de erros da mesma forma - Listar todos os erros manualmente quando você quer todos eles é algo propenso a erros - Você não precisa de nada extravagante pra isso, dá pra ser simples! - Use o padrão de projeto Layer Supertype quando necessário - Aqui vai um segredo: você já usa ele com Rails o tempo todo - Exemplos do padrão Layer Supertype com Rails: - ApplicationController - ApplicationRecord - ApplicationJob
de tratamento inconsistente - Especialmente importante quando sua aplicação tem várias portas de entrada: - Endpoints de API, endpoints com views, background jobs, ActionCable, … - Só usar o rescue_from não torna realmente centralizado - Tome cuidado para não centralizar demais
convenções - Infelizmente, ele não fornece convenções fortes para erros - Podemos criar as nossas próprias, seguindo o Rails-way! - Boas convenções que seguem o Rails-way devem fornecer: - Padrões seguros e confiáveis - Um jeito prático de serem quebradas quando necessário
aplicação, como: - Result object - Railway oriented programming, Trailblazer, … - Monads - Bom, elas são ótimas! Mas… - É importante manter elas sob controle, caso contrário…
para modelar os fluxos da sua aplicação - É impedir que elas "coloram" o seu código - Caso contrário, todo o seu código precisará saber lidar com elas - Mantenha sob controle as abstrações que representam casos de uso: - Services, operations, interactors, … - Use objetos de erros comuns em todo o resto Controllers Jobs Channels Services Operations Interactors Infraestrutura Regras de negócio (Domínio e models)
- Seja intencional e explícito com seus cenários de erro - Abstraia erros da mesma forma que você faz com lógica - Reduza inconsistências centralizando o tratamento de erros - Crie e siga convenções para seu projeto - Mantenha sob controle abordagens que podem afetar o código de toda a sua aplicação