Todas as exceções em Dart são exceções não verificadas: não é necessário declarar os tipos lançados nas funções e capturá-las não é obrigatório.
Existem duas categorias:
Exception:Erros previsíveis ligados à lógica de negócio (problemas de formato, parâmetros inválidos… Recomenda-se capturar e tratar esses casos).Error:Erros fatais do programa (incompatibilidade de tipos, ponteiro nulo, métodos não implementados… Geralmente não são capturados).
Qualquer objeto não nulo pode ser lançado com a palavra-chave throw. Em projetos padronizados, apenas subclasses de Exception/Error são lançadas.
Qualquer exceção não capturada interrompe o isolate atual e causa o crash do aplicativo.
throw: lançar uma exceção
1. Lançar exceções nativas do sistema
void main() {
// Exceção de formato
throw FormatException("É necessário pelo menos um segmento de dados");
}
Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
FormatException: Descrição do erro
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:3:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
Esse código lança uma exceção nativa com uma mensagem personalizada que aparece na execução. Você pode se perguntar qual a utilidade disso, mas o lançamento de exceções é um mecanismo essencial no desenvolvimento. Por exemplo, no cadastro de usuários validamos os dados inseridos: se não estiverem em conformidade com as regras, lançamos imediatamente uma exceção para interromper o fluxo e alertar o usuário, evitando a inserção de dados inválidos e mantendo a integridade das informações.
2. Lançar qualquer objeto
Não recomendado para ambiente de produção
void main() {
throw "Texto descritivo do erro!";
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
Texto descritivo do erro!
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:2:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
3. Usar throw dentro de função de seta (throw é uma expressão)
class Point {}
void distanceTo(Point other) => throw UnimplementedError("Este método não foi implementado");
void main() {
distanceTo(Point());
}
Code language: JavaScript (javascript)
III. Capturar exceções com try /on/catch
Diferenças de sintaxe
on TipoExceção:Apenas combina com exceções do tipo especificado, não é possível acessar o objeto da exceção.catch(e):Captura todas as exceções, a variável e contém a instância da exceção.catch(e, s):e = objeto da exceção, s = pilha de chamadas StackTrace.
1: Capturar um único tipo de exceção com on
// Criar uma classe de exceção personalizada que implementa Exception
class OutOfLlamasException implements Exception {}
// Função que lança a exceção personalizada acima
void breedMoreLlamas() {
throw OutOfLlamasException();
}
void buyMoreLlamas() {
print("A função buyMoreLlamas foi executada");
}
void main() {
try {
breedMoreLlamas(); // Chamar a função com código de risco
} on OutOfLlamasException {
buyMoreLlamas(); // Executado se OutOfLlamasException for capturada
}
}Code language: Dart (dart)
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
A função buyMoreLlamas foi executadaCode language: CSS (css)
try {
// Código suscetível a erros
} on ClasseExceção {
// Lógica executada ao capturar o erro
}Code language: Dart (dart)
try on é apenas uma sintaxe dedicada à captura de exceções por tipo.
2: Captura hierárquica com múltiplos ramos
As correspondências mais precisas são processadas primeiro
class OutOfLlamasException implements Exception {}
void breedMoreLlamas() {
throw FormatException("Erro de formato de dados");
}
void main() {
try {
breedMoreLlamas();
}
// 1. Correspondência exata com a exceção personalizada
on OutOfLlamasException {
print("Ocorreu o erro OutOfLlamasException");
}
// 2. Capturar todas as subclasses de Exception
on Exception catch (e) {
print("Exceção comum de negócio:$e");
}
// 3. Ramo de fallback para Error e qualquer outro objeto lançado
catch (e) {
print("Erro grave desconhecido:$e");
}
}
Code language: Dart (dart)
Saída:Exceção comum de negócio:FormatException: Erro de formato de dados
É possível usar vários blocos on para capturar cada tipo de Exception separadamente, com um catch final como proteção universal.
3: Capturar exceção e imprimir pilha de chamadas StackTrace
void main() {
try {
int a = null;
print(a + 1);
} catch (e, stack) {
print("Mensagem da exceção:$e");
print("Pilha de chamadas completa:\n$stack");
}
}
Code language: Dart (dart)
Esse código exibe não só a mensagem de erro, mas também toda a cadeia de chamadas de funções para facilitar a depuração.
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:3:13: Error: A value of type 'Null' can't be assigned to a variable of type 'int'.
int a = null;Code language: PHP (php)
IV. rethrow relançar exceção
Tratar parcialmente e propagar a exceção para cima
Função: executar parte da lógica de recuperação na função atual, depois enviar a exceção para a função chamadora receber tratamento complementar.
Às vezes não conseguimos resolver o erro totalmente na função corrente; precisamos relançar a exceção para que o código chamador também possa lidar com ela.
void misbehave() {
try {
dynamic foo = true;
print(foo++); // true não aceita incremento, causa erro em tempo de execução
} catch (e) {
print("Tratamento local em misbehave:${e.runtimeType}");
rethrow; // Relançar para o bloco try externo capturar
}
}
void main() {
try {
misbehave();
} catch (e) {
print("Tratamento final em main:${e.runtimeType}");
}
}
Code language: Dart (dart)
Fluxo de execução:
Tratamento local em misbehave:NoSuchMethodError
Tratamento final em main:NoSuchMethodError
Code language: PHP (php)
No código acima, o erro é tratado tanto na função misbehave quanto na main.
V. Bloco finally
Executado obrigatoriamente, com ou sem erro
Dois cenários de uso principais:
- Apenas try + finally: a exceção não é capturada, o aplicativo crasha após executar o finally
- try + catch + finally: tratar o erro primeiro, depois executar finally (exclusivo para liberação de recursos)
1: try + finally
void cleanLlamaStalls() => print("Limpar recursos, bloco executado em qualquer caso");
void breedMoreLlamas() => throw Exception("Ocorreu um erro");
void main() {
try {
breedMoreLlamas();
} finally {
cleanLlamaStalls();
}
}
Code language: Dart (dart)
O código de limpeza roda, mas a exceção não capturada encerra o programa no final.
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Limpar recursos, bloco executado em qualquer caso
Unhandled exception:
Exception: Ocorreu um erro
#0 breedMoreLlamas (file:///D:/dartdemo/firstdart/bin/firstdart.dart:2:27)
#1 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:5)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
2: try + catch + finally
Sintaxe padrão para liberar recursos, por exemplo fechar arquivos abertos
void cleanLlamaStalls() => print("Fechar arquivos / liberar recursos do sistema");
void breedMoreLlamas() => throw FormatException("Falha na análise");
void main() {
try {
breedMoreLlamas();
} catch (e) {
print("Exceção capturada:$e");
} finally {
cleanLlamaStalls();
}
}
Code language: Dart (dart)
Ordem de execução: lançamento da exceção → tratamento no catch → execução do finally
Resultado da execução
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Exceção capturada:FormatException: Falha na análise
Fechar arquivos / liberar recursos do sistema
Code language: JavaScript (javascript)
VI. assert: asserções
Funciona apenas em desenvolvimento/depuração, totalmente desativado em produção
assert(condição booleana, [mensagem de erro opcional])
Lança uma AssertionError se a condição for false; ignorado completamente na versão de produção sem perda de desempenho.
1: Exemplo básico de asserção
void main() {
String? text;
int number = 120;
String url = "http://foxdevelop.com";
assert(text != null); // Verificar se a variável não é nula
assert(number < 100); // Validar intervalo numérico
assert(url.startsWith("https")); // Checar protocolo da URL
}
Code language: JavaScript (javascript)
A execução desse código não exibe nada por padrão!
As asserções vêm desativadas por padrão; é necessário ativar um parâmetro de inicialização para usá-las, veja abaixo.
2: Definir mensagem de erro personalizada para asserção falha
void main() {
String url = "http://test.com";
assert(
url.startsWith("https"),
"O endereço $url deve começar com https",
);
}
Code language: JavaScript (javascript)
Podemos criar livremente a mensagem exibida quando uma asserção falha.
Como ativar as asserções
- Modo Debug do Flutter: asserções ativadas por padrão
- Execução via comando dart:
dart --enable-asserts nome-do-arquivo.dart - Build de produção: todo código de asserção é removido, sem impacto no desempenho
D:\dartdemo\firstdart\bin>dart --enable-asserts firstdart.dart
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
Tanto dart run quanto o comando simples dart desativam as asserções por padrão, é preciso adicionar a flag --enable-asserts:
Exemplo de comando de execução
dart run --enable-asserts main.dartCode language: CSS (css)
Se o terminal já estiver na raiz do projeto, use a versão curta:
Comando de execução:
dart run --enable-asserts
dart run: Executar código fonte Dart diretamente, ideal para testes de desenvolvimento
dart nome-arquivo: Sintaxe simplificada para rodar um arquivo único
dart compile exe: Compilar um executável independente, as asserções sempre ficam desativadas no binário compilado
Os arquivos Dart ficam na pasta bin do projeto. Você pode navegar até bin para rodar o arquivo diretamente ou subir até a raiz do projeto para executar o projeto completo.
dart run –enable-asserts
Abaixo estão os dois métodos: execução a partir da pasta bin e execução a partir da raiz do projeto.
D:\dartdemo\firstdart\bin>dart --enable-asserts firstdart.dart
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)
D:\dartdemo\firstdart\bin>dart run
Building package executable...
Built firstdart:firstdart.
D:\dartdemo\firstdart\bin>cd ..
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
Se a condição da asserção for true, nenhuma exceção será lançada
Modifique o exemplo: troque http por https na URL, altere text != null para text == null e defina number como 99
void main() {
String? text;
int number = 99;
String url = "https://foxdevelop.com";
assert(text == null); // Verificação de nulo
assert(number < 100); // Validação de intervalo numérico
assert(url.startsWith("https")); // Checagem de protocolo URL
}Code language: Dart (dart)
Ao executar novamente, nenhum erro aparece
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.Code language: CSS (css)
VII. Exemplo completo
void cleanResource() => print("finally: liberar recursos ocupados");
void testError() {
try {
int num = 150;
assert(num < 100, "O número deve ser menor que 100");
throw FormatException("Formato de dados inválido");
} on FormatException catch (e) {
print("Exceção de formato capturada:$e");
rethrow;
} finally {
cleanResource();
}
}
void main() {
try {
testError();
} catch (e) {
print("main captura a exceção relançada:$e");
}
}
Code language: PHP (php)
Resultado da execução
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.
finally: liberar recursos ocupados
main captura a exceção relançada:'file:///D:/dartdemo/firstdart/bin/firstdart.dart':
Failed assertion: line 6 pos 12: 'num < 100': O número deve ser menor que 100Code language: PHP (php)
Exemplo completo de todo o fluxo de gerenciamento de exceções e erros