Da trilha de C# Este conceito ainda não saiu como card do dia. ir para o card de hoje

C# Erros Intermediário

Exceções

Em C#, exceções são o mecanismo padrão para sinalizar e tratar erros em tempo de execução. Quando algo inesperado acontece, o código lança (throw) uma exceção; quem chamou pode capturá-la com try/catch e opcionalmente executar código de limpeza com finally.

O bloco try contém o código que pode falhar. Cada catch especifica o tipo de exceção que deseja tratar, permitindo tratamentos diferentes para erros diferentes. O bloco finally sempre executa, tenha havido exceção ou não, sendo ideal para liberar recursos.

Você pode criar exceções próprias herdando de Exception para representar erros específicos do seu domínio. Também pode usar filtros com when para capturar uma exceção apenas se uma condição for verdadeira, evitando catch genéricos e melhorando a legibilidade.

Neste card, veremos como combinar try, catch, finally, throw, exceções personalizadas e filtros when para escrever código robusto e expressivo.

Pontos-chave

  • try delimita o código que pode lançar exceções; catch trata tipos específicos; finally sempre executa.
  • throw lança uma exceção; throw; dentro de um catch relança a exceção original preservando o stack trace.
  • Exceções próprias herdam de Exception (ou de uma subclasse) e geralmente terminam com Exception no nome.
  • Filtros com when permitem capturar uma exceção somente se uma condição for verdadeira.
  • Capture as exceções mais específicas primeiro e evite catch (Exception) genérico sem necessidade.
ExcecoesDemo.cs
using System;

// Exceção personalizada para saldo insuficiente
public class SaldoInsuficienteException : Exception
{
    public decimal SaldoAtual { get; }
    public SaldoInsuficienteException(decimal saldoAtual)
        : base($"Saldo insuficiente: {saldoAtual:C}")
    {
        SaldoAtual = saldoAtual;
    }
}

public class ContaBancaria
{
    public decimal Saldo { get; private set; }

    public ContaBancaria(decimal saldoInicial) => Saldo = saldoInicial;

    public void Sacar(decimal valor)
    {
        if (valor <= 0)
            throw new ArgumentOutOfRangeException(nameof(valor), "Valor deve ser positivo");
        if (valor > Saldo)
            throw new SaldoInsuficienteException(Saldo);
        Saldo -= valor;
    }
}

class Program
{
    static void Main()
    {
        var conta = new ContaBancaria(100m);
        try
        {
            conta.Sacar(150m);
        }
        catch (SaldoInsuficienteException ex) when (ex.SaldoAtual < 200m)
        {
            Console.WriteLine($"Erro tratado: {ex.Message}");
        }
        catch (SaldoInsuficienteException ex)
        {
            Console.WriteLine($"Erro grave: {ex.Message}");
        }
        finally
        {
            Console.WriteLine("Operação finalizada.");
        }
    }
}

Exercícios

  1. 1
    Fácil

    Tratando divisão por zero

    Escreva um programa que leia dois números inteiros e realize a divisão do primeiro pelo segundo. Trate o caso de divisão por zero com try/catch e exiba uma mensagem amigável. Use finally para exibir 'Fim do cálculo.'

    Resolver
  2. 2
    Médio

    Exceção personalizada para idade inválida

    Crie uma exceção personalizada IdadeInvalidaException que herde de Exception. Escreva um método ValidarIdade(int idade) que lance essa exceção se a idade for menor que 0 ou maior que 150. No Main, chame o método dentro de um try e capture a exceção, exibindo a mensagem.

    Resolver
  3. 3
    Desafio

    Filtro com when e relançamento

    Crie um método ProcessarPagamento(decimal valor) que lança SaldoInsuficienteException com a propriedade SaldoAtual. No Main, capture essa exceção usando um filtro when que só trata se SaldoAtual < 100. Caso contrário, relance a exceção com throw;. Use finally para registrar 'Pagamento processado.'

    Resolver

Continue estudando