본문 바로가기
Backend2026년 6월 10일3분 읽기

Express에서 async 에러가 안 잡힐 때 — 핸들링 패턴

YS
김영삼
조회 266
Express에서 async 에러가 안 잡힐 때 — 핸들링 패턴

핵심 요약

Express 4에서 async 핸들러가 던진 에러는 자동으로 에러 미들웨어로 안 가서 요청이 멈추거나 unhandledRejection이 된다. 모든 async 핸들러를 래퍼로 감싸 next(err)로 넘기고, 중앙 에러 미들웨어에서 한 번에 처리하는 게 정석이다.

1. async 래퍼

const wrap = fn => (req, res, next) =>
  Promise.resolve(fn(req, res, next)).catch(next)

app.get('/users', wrap(async (req, res) => {
  const users = await db.users()   // throw 하면 next(err)로 감
  res.json(users)
}))

2. 중앙 에러 미들웨어

app.use((err, req, res, next) => {
  console.error(err)
  res.status(err.status || 500).json({ error: err.message })
})  // 인자 4개여야 에러 미들웨어로 인식

3. 함정

  • 에러 미들웨어는 인자 4개(err, req, res, next)여야 한다 — 하나 빠지면 일반 미들웨어로 취급
  • Express 5는 async 에러를 자동 전달하지만, 여전히 명시적 처리가 안전하다
  • 응답을 두 번 보내지 않도록 res.headersSent 확인

자주 묻는 질문

try/catch를 라우트마다 쓰면 안 되나요?

되지만 반복이 많고 빠뜨리기 쉽습니다. wrap 헬퍼로 한 번 감싸면 모든 라우트가 일관되게 중앙 에러 미들웨어로 흘러갑니다.

Express 5에선 필요 없나요?

5는 async 에러를 자동으로 next에 넘겨줍니다. 다만 중앙 에러 미들웨어 설계는 여전히 필요합니다.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록