AULA 48 MÓDULO 6 backend Node.js ⏱ 50 min

Tratamento de Erros

Estratégia de 3 camadas. AppError: erros customizados com statusCode. asyncHandler. Middleware de erro global.

AppErrorasyncHandlermiddleware de erroisOperationaltry/catch500logs

Estratégia de tratamento de erros

Erros não tratados em Node.js derrubam o processo. Uma estratégia robusta tem 3 camadas: captura em cada async handler, middleware de erro global, e process error handlers.

💥
uncaughtException vs unhandledRejection
process.on('uncaughtException') e process.on('unhandledRejection') são a última linha de defesa. Logar, alertar e derrubar o processo graciosamente.

AppError — classes de erro customizadas

Criar classes de erro customizadas permite carregar statusCode e metadados junto com o erro. O middleware de erro extrai o statusCode e retorna a resposta correta.

🔍
never expose internals
Em produção, erros 5xx devem retornar mensagem genérica. Detalhes técnicos (stack trace, queries) ficam só nos logs — nunca no JSON de resposta.
javascript
// Erros customizados — AppError
class AppError extends Error {
  constructor(message, statusCode = 500, code) {
    super(message)
    this.statusCode = statusCode
    this.code = code
    this.isOperational = true
  }
}

// Erros específicos de domínio
class NotFoundError   extends AppError { constructor(msg) { super(msg, 404, 'NOT_FOUND') } }
class ValidationError extends AppError { constructor(msg) { super(msg, 400, 'VALIDATION') } }
class UnauthorizedError extends AppError { constructor(msg) { super(msg, 401, 'UNAUTHORIZED') } }

// Wrapper para async — elimina try/catch repetitivo
const asyncHandler = fn => (req, res, next) =>
  Promise.resolve(fn(req, res, next)).catch(next)

// Middleware de erro global
app.use((err, req, res, next) => {
  const isProd = process.env.NODE_ENV === 'production'
  logger.error({ err, req: { method: req.method, url: req.url } })
  res.status(err.statusCode || 500).json({
    error: err.isOperational || !isProd ? err.message : 'Erro interno',
    code:  err.code
  })
})

// Uso com asyncHandler
app.get('/users/:id', asyncHandler(async (req, res) => {
  const user = await db.findById(req.params.id)
  if (!user) throw new NotFoundError('Usuário não encontrado')
  res.json(user)
}))
quiz · aula 48
Teste seus conhecimentos
0/3 respondidas
QUESTÃO 01
O que é isOperational em AppError?
QUESTÃO 02
Por que usar asyncHandler?
QUESTÃO 03
Em produção, um erro 500 deve retornar para o cliente...
0/3