ErrorOr para C# (.NET): guia completo de tratamento de erros sem exceções
No desenvolvimento moderno com C# (.NET), o tratamento de erros tradicionalmente se baseia no mecanismo de exceções. No entanto, essa abordagem tem várias desvantagens: as exceções interrompem o fluxo de execução, geram sobrecarga na pilha e, o mais importante, nem sempre sinalizam claramente ao desenvolvedor que um método pode falhar. A biblioteca ErrorOr oferece uma alternativa — uma abordagem funcional onde o resultado da operação é retornado como um objeto especial que pode conter um valor de sucesso ou uma lista de erros.
A ideia central do ErrorOr é tornar o tratamento de erros explícito e type-safe. Em vez de lançar uma exceção, o método retorna um objeto do tipo ErrorOr<TValue>. O código chamador é obrigado a verificar se a operação foi bem-sucedida antes de usar o resultado. Isso previne diversos bugs relacionados a exceções não tratadas, tornando o código mais previsível e fácil de entender.
A biblioteca é inspirada em linguagens com sistemas de tipos avançados, como Rust (tipo Result<T, E>) e F# (tipo Result<'T, 'TError>). O ErrorOr é ideal para Clean Architecture, Domain-Driven Design (DDD) e projetos CQRS, onde é essencial separar claramente cenários de sucesso e erro. Ele também funciona perfeitamente com o padrão "Railway Oriented Programming", permitindo construir cadeias de operações com propagação automática de erros.
Instalação
A instalação da biblioteca ErrorOr em um projeto .NET é feita através do gerenciador de pacotes NuGet. Execute um dos seguintes comandos no terminal ou no console do gerenciador de pacotes:
dotnet add package ErrorOr
Ou, se você estiver usando o Package Manager Console no Visual Studio:
Install-Package ErrorOr
Após a instalação, adicione o namespace no seu arquivo de código:
using ErrorOr;
Início rápido: exemplo funcional mínimo
Vamos escrever uma função simples que divide um número por outro. Em vez de lançar uma exceção ao dividir por zero, retornaremos um ErrorOr<double>.
using ErrorOr;
public static class Calculator
{
public static ErrorOr<double> Divide(double dividend, double divisor)
{
if (divisor == 0)
{
// Retorna um erro se o divisor for zero
return Error.Validation("Calculator.DivisionByZero", "O divisor não pode ser zero.");
}
// Retorna o resultado bem-sucedido
return dividend / divisor;
}
}
// Uso
public class Program
{
public static void Main()
{
ErrorOr<double> result = Calculator.Divide(10, 2);
if (result.IsError)
{
Console.WriteLine($"Operação falhou: {result.FirstError.Description}");
}
else
{
Console.WriteLine($"Resultado: {result.Value}");
}
// Exemplo com erro
ErrorOr<double> errorResult = Calculator.Divide(10, 0);
if (errorResult.IsError)
{
Console.WriteLine($"Operação falhou: {errorResult.FirstError.Description}");
}
}
}
Neste exemplo, vemos os elementos-chave: criação de erro via Error.Validation(), retorno de valor de sucesso (conversão implícita) e verificação do resultado através da propriedade IsError.
Principais métodos, funções e classes
Abaixo está uma análise detalhada dos componentes essenciais da biblioteca ErrorOr. Para cada elemento, são fornecidos a assinatura, descrição e um exemplo de código funcional.
1. Classe ErrorOr<TValue>
Assinatura: public rea