Middleware de erros e tipos de resultado
Projete um manipulador central de erros e um padrão Result tipado; envolva manipuladores assíncronos para encaminhar erros; retorne envelopes de erro consistentes.
Middleware de erros e tipos de resultado é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 3 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de TypeScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de TypeScript Academy inclui 3 aulas no total.
Introdução
Objetivo: centralizar os erros em tempo de execução e retornar um “envelope de erro” JSON consistente. Você criará um tipo Result, um invólucro para manipuladores assíncronos e um middleware robusto de tratamento de erros.
- União discriminada Result<T,E>
- next(err) a partir de manipuladores assíncronos
- Mapeamento de unknown→erro tipado
Tipo Result
Use uma união discriminada para os resultados das funções: { ok: true; value } ou { ok: false; error }. Quem chama a função deve tratar os dois ramos.
// Result pattern for services and controllers
export type Ok<T> = { ok: true; value: T }
export type Err<E> = { ok: false; error: E }
export type Result<T, E = string> = Ok<T> | Err<E>
export const ok = <T>(value: T): Ok<T> => ({ ok: true, value })
export const err = <E>(error: E): Err<E> => ({ ok: false, error })
// Example usage
async function getUserName(id: string): Promise<Result<string, "NOT_FOUND" | "DB">> {
if (id === "missing") return err("NOT_FOUND")
try { return ok("Ada") } catch { return err("DB") }
}Envelope de erro
Normalize unknown em um envelope pequeno e previsível. Evite expor rastreamentos da pilha aos clientes.
// Canonical error envelope
export type ErrorEnvelope = {
error: string
code?: string
details?: unknown
}
export function mapError(u: unknown): ErrorEnvelope {
if (u instanceof Error) return { error: u.message }
if (typeof u === "string") return { error: u }
try { return { error: JSON.stringify(u) } } catch { return { error: "Unknown error" } }
}Invólucro assíncrono e middleware
Envolva qualquer manipulador assíncrono para que as rejeições chamem next(err). O middleware final de tratamento de erros formata o JSON uma única vez.
import express, { Request, Response, NextFunction } from "express"
export const asyncHandler = <P, ResBody, ReqBody, Query>(fn: (req: Request<P, ResBody, ReqBody, Query>, res: Response<ResBody>, next: NextFunction) => Promise<unknown>) => {
return (req: Request<P, ResBody, ReqBody, Query>, res: Response<ResBody>, next: NextFunction) => {
Promise.resolve(fn(req, res, next)).catch(next)
}
}
export function errorMiddleware(err: unknown, _req: Request, res: Response, _next: NextFunction) {
const env = mapError(err)
const status = env.code === "NOT_FOUND" ? 404 : 500
res.status(status).json(env)
}
// Usage
// app.get("/", asyncHandler(async (req, res) => { throw new Error("boom") }))
// app.use(errorMiddleware)Rotas e integração
Combine validação e tratamento de erros: a validação retorna 400 com detalhes; outras rejeições são capturadas pelo middleware central.
import express from "express"
import { z } from "zod"
import { asyncHandler, errorMiddleware } from "./errors"
const createUserSchema = z.object({ name: z.string().min(1) })
const app = express()
app.use(express.json())
app.post("/users", asyncHandler(async (req, res) => {
const parsed = createUserSchema.safeParse(req.body)
if (!parsed.success) {
res.status(400).json({ error: "Invalid body", details: parsed.error.format() })
return
}
res.status(201).json({ id: "u_1", name: parsed.data.name })
}))
app.use(errorMiddleware)
app.listen(3000, () => console.log("http://localhost:3000"))Dicas
Dicas:
- Registre os detalhes no servidor; retorne mensagens mínimas ao cliente.
- Prefira Result tipado nos serviços e faça o mapeamento para HTTP na borda.
- Nunca ignore rejeições — sempre chame
next(err).
Verificação de erros assíncronos
Verificação rápida: qual padrão encaminha corretamente os erros assíncronos?
Recapitulação
Recapitulação: use uma união Result para a lógica de domínio, envolva os manipuladores assíncronos para chamar next e formate os erros uma única vez em um middleware final.
Perguntas Frequentes
A aula “Middleware de erros e tipos de resultado” é grátis?
Sim — o texto completo de “Middleware de erros e tipos de resultado” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de TypeScript Academy, atualize para CoddyKit PRO. O curso de TypeScript Academy inclui 3 aulas no total.
O que vou aprender em “Middleware de erros e tipos de resultado”?
Projete um manipulador central de erros e um padrão Result tipado; envolva manipuladores assíncronos para encaminhar erros; retorne envelopes de erro consistentes. Você pratica TypeScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar TypeScript Academy?
Nenhuma experiência prévia é necessária. TypeScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 3.
Quanto tempo leva a aula “Middleware de erros e tipos de resultado”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de TypeScript Academy?
Sim. Cada aula de TypeScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Tipagem de manipuladores de rotas e Request/Response
- Validação de esquemas com zod e inferência para TS
- Middleware de erros e tipos de resultado