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
-
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.
-
Tipos específicos de exceção: Crie uma função que converta uma String para int. Trate especificamente
FormatExceptione outras exceções de forma diferente. -
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. -
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.
-
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");
}
}