🚀 Capítulo 16: Tratamento de Erros e Exceções (Tema: Sonic)
NOTE
Este capítulo utiliza a temática de Sonic para explicar o Tratamento de Erros. Se o Sonic bater em um espinho sem anéis, dá Game Over. No nosso código, precisamos de “anéis” (Try/Catch) para o servidor não morrer!
1. 🎯 Objetivo da Aula
Compreender como capturar e tratar erros no Backend utilizando blocos try/catch e middlewares de erro, garantindo que o servidor continue rodando e retorne respostas amigáveis.
2. 🏢 O Cenário Prático (Seu Desafio)
Você está jogando Sonic em alta velocidade. De repente, você bate em um robô do Dr. Robotnik.
- Cenário A (Sem tratamento): Você não tinha anéis. O jogo fecha na hora e dá tela preta. Péssima experiência!
- Cenário B (Com tratamento): Você tinha anéis. Você perde os anéis, mas continua correndo.
No nosso servidor, se o código tentar ler um arquivo que não existe ou dividir por zero, ele vai dar “tela preta” (vai cair) se não tratarmos o erro. Seu desafio é blindar o servidor!
3. 🧠 Fundamentos: A Teoria Traduzida
Erros acontecem. O usuário pode digitar dados inválidos, o banco de dados pode cair, ou você pode cometer um erro de digitação no código. O importante é como o sistema reage a isso.
🛡️ 1. O Bloco Try/Catch
É a nossa rede de proteção. Nós “tentamos” (try) executar um código. Se der erro, o fluxo vai direto para o bloco catch (capturar), onde decidimos o que fazer, em vez de derrubar o sistema.
try {
// Código que pode dar erro (ex: ler banco)
} catch (error) {
// O que fazer se der erro (ex: avisar o usuário)
}🚨 2. Retornando Status Corretos
Quando um erro acontece, o Backend DEVE retornar um código de status HTTP adequado para que o Frontend saiba o que fazer:
- Erro de digitação do usuário? Retorne
400 Bad Request. - Erro que você não sabe o que foi? Retorne
500 Internal Server Error.
4. 📖 Exemplo Guiado: Protegendo uma Rota
app.get('/perfil/:id', (req, res) => {
try {
const id = req.params.id;
if (id === "0") {
// Forçando um erro para o exemplo
throw new Error("ID inválido do Sonic!");
}
res.send("Perfil do herói carregado!");
} catch (error) {
// Captura o erro e responde bonito
res.status(400).json({
sucesso: false,
mensagem: error.message
});
}
});5. 🛠️ Prática Obrigatória 1: Blindando a Divisão
Crie uma rota GET /divisao que receba dois números via Query Params (?a=10&b=2).
- Tente fazer a divisão de
aporb. - Use
try/catch. - Se o usuário tentar dividir por zero (
b=0), lance um erro e retorne status400com a mensagem:"Não é possível dividir por zero!".
6. 🛠️ Prática Obrigatória 2: O Perigo da Tela Preta
Por que é considerado uma falha grave de segurança deixar que o erro original do sistema (com todo o caminho das pastas do computador) apareça na tela para o usuário final quando dá um erro 500?
7. 📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)
- Faça o Commit: No GitHub Desktop, digite a mensagem (ex:
Finaliza Capítulo 16 Backend) e clique em Commit to main. - Envie para a Nuvem (Push): Clique em Push origin.
8. 📂 Estrutura de Pastas
mod_07_backend_e_apis/
├── capitulos/
│ ├── capitulo_16_erros.md
│ └── codigos/
│ └── cap16/
│ └── divisao_segura.js9. 💡 Checkpoint de Lógica
Se colocarmos um try/catch gigante em volta de todo o código do servidor, resolvemos todos os problemas de erro do sistema? Isso é considerado uma boa prática?
10. 🔥 Desafio de Fixação
Pesquise o que são os Global Error Handlers (Manipuladores Globais de Erro) no Express e como eles ajudam a centralizar o tratamento de erros.
🔑 Gabarito de Código/Fórmulas
Gabarito da Prática 1:
app.get('/divisao', (req, res) => {
try {
const a = parseFloat(req.query.a);
const b = parseFloat(req.query.b);
if (b === 0) {
throw new Error("Não é possível dividir por zero!");
}
res.json({ resultado: a / b });
} catch (error) {
res.status(400).json({ erro: error.message });
}
});