🚀 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 a por b.
  • Use try/catch.
  • Se o usuário tentar dividir por zero (b=0), lance um erro e retorne status 400 com 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)

  1. Faça o Commit: No GitHub Desktop, digite a mensagem (ex: Finaliza Capítulo 16 Backend) e clique em Commit to main.
  2. 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.js

9. 💡 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 });
    }
});

Capitulo Anterior | Proximo Capitulo