การจัดการ Error ใน TypeScript
การกระจาย error response ไปทั่วทุก handler รับประกันความไม่สม่ำเสมอ แทนที่จะทำเช่นนั้น ให้ throw typed error ใน handler ของคุณ แล้วแปลงเป็น problem+json ที่จุดเดียว
typed error + central handler
หัวข้อที่มีชื่อว่า “typed error + central handler”flowchart LR H[Handler throws ApiError] --> M[Error middleware] M --> P[Map to problem+json] P --> R[Response with correct status]
นิยาม error type ที่พก status และ field ของ problem ไว้ในตัว แล้วให้ handler เดียวเป็นตัวแปลงออกไป อะไรที่ไม่คาดคิดจะตกไปเป็น 500 และ stack trace จะไม่รั่วออกไปถึง client
ทำไมต้องรวมศูนย์
หัวข้อที่มีชื่อว่า “ทำไมต้องรวมศูนย์”- ความสม่ำเสมอ — ทุก error ออกไปด้วยรูปทรงเดียวกัน
- ความปลอดภัย — error ที่ไม่คาดคิดกลายเป็น
500แบบทั่วไป; ส่วนภายในไม่รั่วไหล - code น้อยลง — handler แค่ throw หนึ่งบรรทัด; ไม่ต้องสร้าง response เองทุกตัว
| ข้อดี (Centralized Error Handling) | ข้อแลกเปลี่ยน |
|---|---|
| error format สม่ำเสมอทั้ง API — ไม่มี special case | setup middleware เพิ่มงาน upfront |
| ป้องกัน internal error leak ไปถึง client | error 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