Mobile App Development · Dart/Flutter

17 · Exceções — Desafios

Dois cenários mais próximos do mundo real: um validador de cadastro com várias regras e um caixa eletrônico com exceção customizada.

Desafio 1

desafio_01_validador_cadastro.dart

Três funções validam nome, idade e e-mail, cada uma lançando Exception com throw quando a regra é violada. Em main, um único try/catch envolve as três chamadas em sequência: a primeira validação que falhar interrompe o restante e é capturada. Com idade 17 (menor de idade), validarNome passa, mas validarIdade lança a exceção — validarEmail nunca chega a ser chamada. Se todas as validações passassem, o programa imprimiria Cadastro valido. em vez da mensagem de erro.

// Desafio: validador de cadastro com múltiplas funções de validação.
// Cada função valida uma regra específica e lança Exception se a regra for violada.
// O try/catch captura a primeira falha e encerra o processo de validação.

// Valida que o nome não está vazio nem contém apenas espaços.
void validarNome(String nome) {
  if (nome.trim().isEmpty) {
    throw Exception('Nome nao pode ficar vazio.');
  }
}

// Valida que a idade é positiva e que o usuário é maior de idade.
void validarIdade(int idade) {
  if (idade < 0) {
    throw Exception('Idade nao pode ser negativa.');
  }

  if (idade < 18) {
    throw Exception('Cadastro permitido apenas para maiores de idade.');
  }
}

// Valida que o e-mail contém o caractere '@', indicando formato básico correto.
void validarEmail(String email) {
  if (!email.contains('@')) {
    throw Exception('E-mail invalido.');
  }
}

void main() {
  String nome = 'Ana';
  int idade = 17; // Menor de idade — vai lançar uma Exception.
  String email = 'ana@email.com';

  // Executa as validações em sequência.
  // Se qualquer validação falhar, o catch captura a exceção e encerra.
  try {
    validarNome(nome);
    validarIdade(idade); // Lança Exception porque idade < 18.
    validarEmail(email); // Nunca chegará aqui neste exemplo.
    print('Cadastro valido.');
  } catch (erro) {
    // Exibe a primeira falha de validação encontrada.
    print('Falha no cadastro: $erro');
  }
}

Saída esperada

Falha no cadastro: Exception: Cadastro permitido apenas para maiores de idade.

Como executar

dart run 17-Excecoes/03_Desafios/codigo_fonte/desafio_01_validador_cadastro.dart

Desafio 2

desafio_02_caixa_eletronico.dart

Simula um caixa eletrônico com a exceção customizada SaldoInsuficienteException e dois blocos de captura distintos: on SaldoInsuficienteException catch (erro) trata especificamente saldo insuficiente, enquanto um catch genérico trata qualquer outro erro (como valor de saque inválido). Com saldo de 250 e saque de 300, sacar() lança SaldoInsuficienteException, capturada pelo primeiro bloco.

// Desafio: simular um caixa eletrônico com exceção customizada e múltiplos 'on'.
// Demonstra como distinguir diferentes tipos de erros usando 'on TipoEspecifico'.

// Exceção customizada para saldo insuficiente.
class SaldoInsuficienteException implements Exception {
  final String mensagem;

  SaldoInsuficienteException(this.mensagem);

  @override
  String toString() => mensagem;
}

// Função que realiza o saque e retorna o novo saldo.
// Usa parâmetros nomeados (saldo: e valor:) para maior clareza na chamada.
double sacar({required double saldo, required double valor}) {
  // Valida que o valor do saque é positivo — lança Exception genérica.
  if (valor <= 0) {
    throw Exception('Valor de saque deve ser maior que zero.');
  }

  // Valida que há saldo suficiente — lança exceção customizada específica.
  if (valor > saldo) {
    throw SaldoInsuficienteException('Saldo insuficiente.');
  }

  // Retorna o saldo restante após o saque.
  return saldo - valor;
}

void main() {
  double saldo = 250;
  double valorSaque = 300; // Valor maior que o saldo — vai lançar exceção.

  try {
    // Tenta realizar o saque; lança SaldoInsuficienteException.
    saldo = sacar(saldo: saldo, valor: valorSaque);
    print('Saque aprovado. Novo saldo: R\$ ${saldo.toStringAsFixed(2)}');
    // Captura especificamente SaldoInsuficienteException com mensagem amigável.
  } on SaldoInsuficienteException catch (erro) {
    print('Saque recusado: $erro');
    // Captura qualquer outra exceção não prevista acima (ex.: valor inválido).
  } catch (erro) {
    print('Erro: $erro');
  }
}

Saída esperada

Saque recusado: Saldo insuficiente.

Como executar

dart run 17-Excecoes/03_Desafios/codigo_fonte/desafio_02_caixa_eletronico.dart