ข้ามไปยังเนื้อหา

การจัดการ Error ใน TypeScript

การกระจาย error response ไปทั่วทุก handler รับประกันความไม่สม่ำเสมอ แทนที่จะทำเช่นนั้น ให้ throw typed error ใน handler ของคุณ แล้วแปลงเป็น problem+json ที่จุดเดียว

flowchart LR
  H[Handler throws ApiError] --> M[Error middleware]
  M --> P[Map to problem+json]
  P --> R[Response with correct status]
handler โยน error; ที่เดียวทำหน้าที่ map error เป็น response

นิยาม error type ที่พก status และ field ของ problem ไว้ในตัว แล้วให้ handler เดียวเป็นตัวแปลงออกไป อะไรที่ไม่คาดคิดจะตกไปเป็น 500 และ stack trace จะไม่รั่วออกไปถึง client

JavaScript
  • ความสม่ำเสมอ — ทุก error ออกไปด้วยรูปทรงเดียวกัน
  • ความปลอดภัย — error ที่ไม่คาดคิดกลายเป็น 500 แบบทั่วไป; ส่วนภายในไม่รั่วไหล
  • code น้อยลง — handler แค่ throw หนึ่งบรรทัด; ไม่ต้องสร้าง response เองทุกตัว
ข้อดี (Centralized Error Handling)ข้อแลกเปลี่ยน
error format สม่ำเสมอทั้ง API — ไม่มี special casesetup middleware เพิ่มงาน upfront
ป้องกัน internal error leak ไปถึง clienterror middleware ที่ผิดทำให้ error ทั้งหมดพัง
logging ครบถ้วนในที่เดียว — ง่ายต่อ monitoringต้องออกแบบ error class hierarchy ให้ดี
retry logic ใน client ทำงานได้ถูกต้องcustom error class ใน TypeScript ต้องระวัง transpilation

try/catch ใน Controller ทุกตัว อาการ:

  • ทุก route handler มี try/catch ของตัวเอง
  • error format แตกต่างกัน — บาง route ส่ง { error: "..." }, บางส่ง { message: "..." }
  • ใช้ error middleware กลาง: app.onError((err, c) => { ... })

ไม่ Log Error ก่อน Return อาการ:

  • error handler ส่ง response โดยไม่ log
  • production มี 500 error แต่ไม่มี log ให้ debug
  • log error พร้อม request context (userId, path, method) ก่อนส่ง response

💡 ตัวอย่างจากของจริง

Hono (framework ที่ course ใช้):

  • app.onError((err, c) => { ... }) — global error handler
  • จัดการ error ทุกประเภทในที่เดียว

Express.js:

  • error middleware 4 parameters: (err, req, res, next)
  • Airbnb ใช้ centralized error handler ที่ log ไปยัง monitoring system ก่อน return response
ประโยชน์หลักของ central error handler คืออะไร?
error ที่ไม่คาดคิด (ไม่ได้คาดการณ์ไว้) ควรถูกส่งกลับไปยัง client อย่างไร?
ในรูปแบบนี้ handler ส่งสัญญาณความล้มเหลวอย่างไร?