ทำไมการจัดการ Error ใน JavaScript ถึงเป็นเรื่องท้าทาย?

– Error Handling เป็นเรื่องใหญ่ เพราะในซอฟต์แวร์จริง ทุกอย่างมีโอกาสผิดพลาด เช่น network ล่ม, ข้อมูลไม่ครบ ฯลฯ

.

– การจัดการ error ที่ดีจะช่วยให้แอปไม่ crash เฉย ๆ แต่แจ้ง error ที่เข้าใจง่ายกับผู้ใช้ และ log ข้อมูลที่เป็นประโยชน์กับ dev

.

– พื้นฐานของ Error Handling ใน JavaScript

เครื่องมือหลักคือ try…catch, throw และ Error object

.

– Error ที่ไม่ถูก catch จะ “bubble” (ลอยขึ้นบน) ไปถึง global scope แล้วทำให้แอปหยุดหรือแสดง warning

.

– ถ้าเป็น async (Promise/async-await) ก็ใช้ .catch() หรือใส่ try…catch รอบ await

.

– ข้อควรระวังและจุดอ่อนของ JavaScript

JS สามารถ throw อะไรก็ได้ (string, number, object…) ไม่จำเป็นต้องเป็น Error ทำให้ใน catch อาจจะเจออะไรก็ได้ ต้องตรวจสอบเอง

.

– TypeScript ก็ช่วยไม่ได้มาก เพราะไม่สามารถรู้ได้ว่า error ที่ throw จะเป็นชนิดอะไร ต้องใช้ unknown หรือ any

.

– หลาย ๆ ไลบรารี (เช่น Supabase) เปลี่ยนจาก throw มาเป็น return object ที่มี error property แทน ซึ่งควบคุมได้ง่ายกว่า

.

– โค้ด Utility ง่าย ๆ ที่ใช้ได้จริง (ดีและ practical สำหรับโปรเจกต์ JavaScript/TypeScript ทั่วไป)

parseError: รับ error (unknown) แล้ว return เป็นข้อความ string ที่อ่านเข้าใจง่ายเสมอ ตัวอย่างโค้ด

export const parseError = (error: unknown) => {

if (typeof error === ‘string’) {

return error;

}

if (error instanceof Error) {

return error.message;

}

return ‘An error occurred’;

};

handleError: เรียก parseError แล้วเอาไปโชว์ toast/error UI (หรือจะ log ก็ได้) ตัวอย่างโค้ด

import { toast } from ‘sonner’;

import { parseError } from ‘./parse’;

export const handleError = (title: string, error: unknown) => {

const description = parseError(error);

toast.error(title, { description });

};

ตัวอย่าง การใช้กับ try / catch

import { handleError } from ‘@/lib/error/handle’;

try {

throw new Error(‘Something went wrong’);

} catch (err) {

handleError(‘Something went wrong’, err);

}

.

ตัวอย่างการใช้กับ promise chains

import { handleError } from ‘@/lib/error/handle’;

fetch(‘https://api.example.com/data‘)

.then((response) => response.json())

.then(console.log)

.catch(handleError);

.

– ความคิดเห็นจาก dev สายต่าง ๆ

1. Just Use Try/Catch

หลายคนบอกว่า try/catch ธรรมดาก็พอแล้ว

ส่วนมากนิยมจับ error แค่ในจุดบน ๆ ของแอป เช่น React Error Boundary หรือ Express middleware แล้วให้ error bubble ขึ้นมา

2. neverthrow

ไลบรารีที่เอา pattern แบบ Rust (Result/Ok/Err) มาใช้ใน TypeScript

ทุก function จะ return ว่าผ่าน/ไม่ผ่านแบบชัดเจน ต้อง handle error case ทุกครั้ง

ปลอดภัย, type-safe, explicit แต่โค้ดจะ verbose ขึ้น และมี dependency

3. Effect

เป็น functional effect system ที่จัดการ error, async, dependency ฯลฯ แบบ Haskell/Scala

Error type ถูก track ใน type system – ไม่ handle ครบ, โค้ดไม่ compile

เหมาะกับโค้ดฐานใหญ่ ๆ, ต้องการความ robust, แต่ “หนัก” มาก ไม่เหมาะเอามาใส่เล่น ๆ

ทำไมถกกันไม่จบ?

JavaScript ยืดหยุ่นสูง throw อะไรก็ได้ ไม่ force dev ให้ระบุ error ชนิดไหน

TypeScript ก็ไม่ได้ช่วยด้านนี้มากนัก เพราะทีมงานคิดว่าไม่เหมาะจะใส่ checked exception/throws keyword ในภาษา

สุดท้าย ไม่มีวิธีไหน “ถูก” หรือ “ผิด” เสียทีเดียว

.

ข้อแนะนำสรุปสำหรับ dev

1. เริ่มจากพื้นฐาน ใช้ try/catch ให้ถูกที่ อย่าปล่อยให้ error เงียบ

2. ตั้งกติกาทีม เช่น ห้าม throw string, ต้องใช้ utility เดียวกัน, ต้อง log error เสมอ ฯลฯ

3. ใช้ utility function (อย่าง parseError/handleError) หรือพิจารณา lib เสริมเช่น neverthrow/Effect ถ้าตรงกับ use case

4. สำคัญที่สุดคืออย่าปล่อย error เงียบ จะใช้วิธีไหนก็ได้ ขอแค่มีแนวทางและใช้สม่ำเสมอ

.

การจัดการ error ไม่มีวิธีที่ “ดีที่สุด” แต่สิ่งที่แย่ที่สุดคือไม่จัดการอะไรเลย

โค้ชเอก

Principal Technical Coach

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

This site uses Akismet to reduce spam. Learn how your comment data is processed.