Exceptions são muito intrusivas

No post anterior, compartilhei um exemplo de como containers podem nos ajudar a deixar o código mais claro sobre os resultados de um método.

public interface IEmployeeRepository
{
  Option<Employee> GeyById(string id);
}
 
class EmployeeRepository : IEmployeeRepository
{
  public Option<Employee> GeyById(string id)
    =>; new DbContext().Find(id);
}

E o que temos sobre Exceptions?! O método GetById irá lançar uma exception se alguma coisa der errado (se não for possível conectar com o banco, por exemplo), mas não há nada sobre isso na assinatura do método.

Either

Uma abordagem superior seria:

public interface IEmployeeRepository
{
    Either<Exception, Option<Employee>> GeyById(string id);
}

class EmployeeRepository : IEmployeeRepository
{
    public Either<Exception, Option<Employee>> GeyById(string id)
    {
        try
        {
            return new DbContext().Find(id);
        }
        catch (Exception e)
        {
            return e;
        }
    }
}

O tipo Either é apenas uma struct comum com conversões implícitas e algumas operações funcionais. Ele permite diferentes tipos de retorno. Neste exemplo, estamos usando o container para tornar explícito que o método pode resultar tanto uma instância de Employee quanto uma exceção.

Try

Eu amo o Either, mas ele não é bom o suficiente! Eu tenho trabalhando bastante para tornar o meu código ainda mais claro.

public interface IEmployeeRepository
{
    Try<Exception, Option<Employee>> GeyById(string id);
}

class EmployeeRepository : IEmployeeRepository
{
    public Try<Exception, Option<Employee>> GeyById(string id)
        => Try.Run(return new DbContext().Find(id));
}

O tipo Try, assim como Either, é uma struct que provê conversões implícitas e algumas operações muito básicas. Ela permite que diferentes tipos de retorno para falha e para sucesso.

A coisa mais interessante sobre esta abordagem é que os programadores que consomem EmployeeRepository são agora forçados a tratar exceções.

public IActionResult Get(string id) => _repository.GetById(id).Match<IActionResult>(
  failure: _ => DatabaseError(),
  success: e => e .Match<IActionResult>(
    some: employee => Ok(employee),
    none: () => NotFound()
  ));

Implementações de Either e Try estão disponíveis no meu github.

Compartilhe este insight:

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mais insights para o seu negócio

Veja mais alguns estudos e reflexões que podem gerar alguns insights para o seu negócio:

Mudança nunca é fácil. Em uma organização, então, este tema costuma ser algo bem complicado. A execução da estratégia implica...
Hoje completo 39 anos! Estou em Uberlândia, em um hotel, descansando após um dia de muito trabalho (e um bocado...
Software em funcionamento é mais relevante que documentação abrangente. Concordo com esse princípio expresso no manifesto ágil. Entretanto, acho que...
“Microsserviços” é um trending topic. Grandes empresas estão tentando associar suas tecnologias com este conceito. Entretanto, é importante que se...
A pergunta do título, embora simples, não é fácil de responder. De qualquer forma, o conhecimento necessário para respondê-la é...
O ano era 2001 ou 2002. Não lembro ao certo. Eu era um jovem programador, pai recente, tentando “encontrar meu...

Inscrição realizada com sucesso!

No dia da masterclass você receberá um e-mail com um link para acompanhar a aula ao vivo. Até lá!

A sua subscrição foi enviada com sucesso!

Aguarde, em breve entraremos em contato com você para lhe fornecer mais informações sobre como participar da mentoria.

Crie sua conta

Preencha os dados para iniciar o seu cadastro no plano anual do Clube de Estudos:

Crie sua conta

Preencha os dados para iniciar o seu cadastro no plano mensal do Clube de Estudos:

× Precisa de ajuda?