Pular para o conteúdo principal

Tratamento de Erros

try / catch

O tratamento de erros em Dart usa blocos try-catch:

try {
int resultado = 10 ~/ 0; // Divisão por zero
print(resultado);
} catch (e) {
print("Erro: $e");
}

Tipos específicos de exceção

try {
int numero = int.parse("abc"); // Erro de parsing
} on FormatException {
print("Formato inválido");
} on Exception catch (e) {
print("Exceção: $e");
} catch (e) {
print("Erro desconhecido: $e");
}

throw e rethrow

Você pode lançar exceções manualmente:

void verificarIdade(int idade) {
if (idade < 0) {
throw ArgumentError("Idade não pode ser negativa");
}
if (idade > 150) {
throw ArgumentError("Idade inválida");
}
}

try {
verificarIdade(-5);
} catch (e) {
print("Erro: $e");
}

rethrow relança a exceção capturada:

void processar() {
try {
int resultado = 10 ~/ 0;
} catch (e) {
print("Erro capturado: $e");
rethrow; // Relança a exceção
}
}

finally

O bloco finally sempre é executado, independentemente de ocorrer erro ou não:

try {
// Código que pode gerar erro
int resultado = 10 ~/ 2;
print(resultado);
} catch (e) {
print("Erro: $e");
} finally {
print("Sempre executa");
}

Exceções customizadas

Você pode criar suas próprias exceções:

class ReservaInsuficienteException implements Exception {
final String mensagem;
ReservaInsuficienteException(this.mensagem);


String toString() => mensagem;
}

class ReservaDeLivros {
int quantidade = 100;

void emprestar(int quantidade) {
if (quantidade > this.quantidade) {
throw ReservaInsuficienteException("Livros insuficientes. Disponível: ${this.quantidade}");
}
this.quantidade -= quantidade;
}
}

Exercícios

  1. try-catch básico: Crie uma função que divida dois números. Use try-catch para tratar divisão por zero e imprima uma mensagem de erro apropriada.

  2. Tipos específicos de exceção: Crie uma função que converta uma String para int. Trate especificamente FormatException e outras exceções de forma diferente.

  3. throw e exceções customizadas: Crie uma exceção customizada IdadeInvalidaException. Crie uma função que valide a idade de uma pessoa (deve estar entre 0 e 150) e lance essa exceção se a idade for inválida.

  4. finally: Crie uma função que simule uma operação de arquivo (abrir, processar, fechar). Use try-catch-finally para garantir que o arquivo seja fechado mesmo se ocorrer um erro.

  5. rethrow: Crie uma função que chame outra função que pode lançar exceção. Capture a exceção, registre um log, e depois relance a exceção usando rethrow.

Soluções

Ver solução do exercício 1
double dividir(double a, double b) {
if (b == 0) {
throw ArgumentError("Divisão por zero não é permitida");
}
return a / b;
}

void main() {
try {
double resultado = dividir(10, 0);
print("Resultado: $resultado");
} catch (e) {
print("Erro: $e");
}

try {
double resultado = dividir(10, 2);
print("Resultado: $resultado"); // 5.0
} catch (e) {
print("Erro: $e");
}
}
Ver solução do exercício 2
int? converterParaInt(String valor) {
try {
return int.parse(valor);
} on FormatException {
print("Erro de formato: '$valor' não é um número válido");
return null;
} catch (e) {
print("Erro desconhecido: $e");
return null;
}
}

void main() {
print(converterParaInt("123")); // 123
print(converterParaInt("abc")); // null (FormatException)
print(converterParaInt("12.5")); // null (FormatException)
}
Ver solução do exercício 3
class IdadeInvalidaException implements Exception {
final String mensagem;
IdadeInvalidaException(this.mensagem);


String toString() => mensagem;
}

void validarIdade(int idade) {
if (idade < 0) {
throw IdadeInvalidaException("Idade não pode ser negativa: $idade");
}
if (idade > 150) {
throw IdadeInvalidaException("Idade inválida (muito alta): $idade");
}
print("Idade válida: $idade");
}

void main() {
try {
validarIdade(25);
validarIdade(-5);
} on IdadeInvalidaException catch (e) {
print("Erro de validação: $e");
}

try {
validarIdade(200);
} on IdadeInvalidaException catch (e) {
print("Erro de validação: $e");
}
}
Ver solução do exercício 4
bool arquivoAberto = false;

void abrirArquivo() {
arquivoAberto = true;
print("Arquivo aberto");
}

void processarArquivo() {
if (arquivoAberto) {
print("Processando arquivo...");
throw Exception("Erro ao processar arquivo");
}
}

void fecharArquivo() {
if (arquivoAberto) {
arquivoAberto = false;
print("Arquivo fechado");
}
}

void operarArquivo() {
try {
abrirArquivo();
processarArquivo();
} catch (e) {
print("Erro durante processamento: $e");
} finally {
fecharArquivo();
print("Operação finalizada (arquivo sempre fechado)");
}
}

void main() {
operarArquivo();
}
Ver solução do exercício 5
void operacaoRiscosa() {
throw ArgumentError("Algo deu errado na operação");
}

void processarComLog() {
try {
operacaoRiscosa();
} catch (e) {
print("Log: Erro capturado em ${DateTime.now()}: $e");
rethrow;
}
}

void main() {
try {
processarComLog();
} catch (e) {
print("Erro final: $e");
}
}