Skip to main content


Tratamento de erros


O tratamento de erros é a forma de lidar com problemas que podem acontecer durante a execução do programa. Dentre as possibilidades, temos:

  • Converter texto inválido para número
  • Abrir arquivo que não existe
  • Dividir valor incorreto
  • Conectar em um serviço indisponível
  • Receber dados inválidos do usuário

Em Dart, erros normalmente são tratados com:

  • try
  • catch
  • on
  • finally
  • throw


Erro sem tratamento


Veja um exemplo de código que não possui tratamento de erro (vai dar erro):

void main() {
String entrada = 'abc';

int numero = int.parse(entrada);

print(numero);
}

Esse código tenta converter 'abc' para inteiro, mas 'abc' não é um número e sim uma string.



Usando try e catch


Ainda usando o exemplo de Erro sem tratamento, vamos usar o try para escrever o código que pode causar um erro e depois um catch para tratar esse erro caso aconteça.

void main() {
String entrada = 'abc';

try {
int numero = int.parse(entrada);
print(numero);
} catch (erro) {
print('Valor inválido');
}
}


Capturando o erro e o stack trace


O catch pode receber dois valores:

catch (erro, stackTrace)

O erro é o erro gerado, se usarmos ele como variável $erro, vamos ver qual erro foi emitido, como exemplo: FormatException: Invalid radix-10 number.


Já o stackTrace guarda o caminho interno do erro, o que é útil para debug.



Usando on


Se quisermos tratar um tipo específico de erro, devemos usar o on.

void main() {
String entrada = 'abc';

try {
int numero = int.parse(entrada);
print(numero);
} on FormatException {
print('O texto informado não é um número válido');
}
}


Usando on com catch


Nós podemos ainda usar on e catch juntos.

void main() {
String entrada = 'abc';

try {
int numero = int.parse(entrada);
print(numero);
} on FormatException catch (erro) {
print('Erro de formato: $erro');
} catch (erro) {
print('Erro desconhecido: $erro');
}
}

Isso é útil para capturar um erro específico e ainda capturar qualquer outro erro que não foi tratado.



Usando finally


O bloco finally é usado para executar algo no final, independente se houve erro ou não. Ele é muito útil para liberar recursos, fechar arquivos, encerrar conexões, etc.

void main() {
String entrada = '123';

try {
int numero = int.parse(entrada);
print('Número: $numero');
} catch (erro) {
print('Erro: $erro');
} finally {
print('Fim da operação');
}
}

Uma dica é usar o finally para ações que precisam acontecer sempre.



Lançando erro com throw


Podemos gerar um erro manualmente usando throw.

double sacar(double saldo, double valor) {
if (valor <= 0) {
throw Exception('Valor de saque inválido');
}

if (valor > saldo) {
throw Exception('Saldo insuficiente');
}

return saldo - valor;
}

void main() {
try {
double saldoFinal = sacar(100.00, 150.00);
print('Saldo final: $saldoFinal');
} catch (erro) {
print('Erro: $erro');
}
}


Criando uma exceção própria


Podemos criar nossa própria classe de exceção.

class SaldoInsuficienteException implements Exception {
String mensagem;

SaldoInsuficienteException(this.mensagem);

@override
String toString() {
return 'SaldoInsuficienteException: $mensagem';
}
}

double sacar(double saldo, double valor) {
if (valor > saldo) {
throw SaldoInsuficienteException('Saldo disponível: R\$ $saldo');
}

return saldo - valor;
}

void main() {
try {
double saldoFinal = sacar(100.00, 150.00);
print(saldoFinal);
} on SaldoInsuficienteException catch (erro) {
print(erro);
}
}


tryParse: alternativa melhor para conversão


Nem sempre precisamos usar try/catch. Quando vamos converter texto em número, o Dart possui o tryParse.

void main() {
String entrada = 'abc';

int? numero = int.tryParse(entrada);

if (numero == null) {
print('Número inválido');
} else {
print('Número: $numero');
}
}

O tryParse tenta converter o texto para inteiro, se conseguir, retorna um int. Se não conseguir, retorna null.



9.14 rethrow


Use rethrow quando você captura um erro, faz alguma ação e quer lançar o mesmo erro novamente.

void processarPagamento() {
try {
int.parse('abc');
} catch (erro) {
print('Registrando erro no log: $erro');
rethrow;
}
}

void main() {
try {
processarPagamento();
} catch (erro) {
print('Erro tratado na main: $erro');
}
}