ด้วยสํานึกในพระมหากรุณาธิคุณสมเด็จพระนางเจ้าสิริกิติ์เป็นล้นพ้นอันหาที่สุดมิได้


การจัดการข้อผิดพลาด (Exception Handling) ในภาษา TypeScript

บทความใหม่ ไม่กี่เดือนก่อน โดย Ninenik Narkdee
typescript

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ typescript

ดูแล้ว 151 ครั้ง


ใน TypeScript การจัดการข้อผิดพลาด (หรือที่เรียกว่า Errors) เป็นกลไกที่ช่วยให้โปรแกรมทำงานต่อไปได้ แทนที่จะหยุดทำงานทันทีเมื่อเกิดปัญหาที่ไม่คาดคิด

 

1. การกำหนดข้อผิดพลาดด้วย throw

 

ใน TypeScript การสร้างและส่งข้อผิดพลาดออกไปใช้คีย์เวิร์ด throw โดยข้อปฏิบัติที่ดีที่สุดคือการส่ง Object ที่สืบทอดมาจากคลาส Error

 

A. การสร้าง Custom Error

 

TS แนะนำให้สร้างคลาสข้อผิดพลาดเฉพาะเจาะจงโดยการ extends Error (เทียบเท่ากับการ implements Exception ใน Dart แต่เป็นมาตรฐานของ JS/TS)

TypeScript
// Custom Error Class
class WithdrawError extends Error {
    constructor(message?: string) {
        super(message); // เรียก constructor ของ Error class
        this.name = 'WithdrawError'; // กำหนดชื่อ Error (สำคัญในการระบุชนิด)
        // Object.setPrototypeOf(this, WithdrawError.prototype); // สำหรับ JS เก่า
    }
}

// การโยนข้อผิดพลาด (Throwing)
function checkWithdraw(deposit: number, withdraw: number): void {
    if (withdraw > deposit) {
        // โยน Custom Error
        throw new WithdrawError('ยอดเงินไม่เพียงพอ'); 
    }
    if (withdraw <= 0) {
        // โยน Base Error
        throw new Error('ยอดเงินที่ต้องการถอนต้องมากกว่า 0'); 
    }
}

ข้อควรจำ: ใน TS/JS สามารถ throw ค่าพื้นฐาน (เช่น throw "String") ได้ แต่ ไม่ควรทำ เพราะจะทำให้การตรวจสอบชนิดของข้อผิดพลาดทำได้ยาก


 

2. การตรวจจับและจัดการด้วย try...catch

 

เราใช้บล็อก try เพื่อครอบโค้ดที่อาจเกิดข้อผิดพลาด และใช้ catch เพื่อจัดการข้อผิดพลาดที่ถูกโยนมา

 

A. การใช้งาน try...catch พื้นฐาน

 

TypeScript
function runTransaction() {
    try {
        checkWithdraw(200, 300); // โค้ดที่อาจเกิดข้อผิดพลาด
    } catch (e) {
        // e คือ error object ที่ถูก throw ออกมา
        console.error("Transaction failed:", e.message); 
        // Output: Transaction failed: ยอดเงินไม่เพียงพอ
    }
}

 

B. การระบุชนิดข้อผิดพลาด (ใช้ instanceof แทน Dart on)

 

TypeScript ไม่มีคีย์เวิร์ด on เหมือน Dart ในการระบุชนิดของ Exception โดยตรงใน catch block แต่เราใช้วิธีการตรวจสอบชนิดของ Error Object ด้วย instanceof แทน

TypeScript
function runSpecificCatch() {
    try {
        checkWithdraw(200, 300); 
    } catch (error) {
        // 1. ตรวจสอบชนิด Custom Error ก่อน
        if (error instanceof WithdrawError) {
            console.warn(`[Withdraw Check] - ${error.message}`);
        } 
        // 2. ตรวจสอบชนิด Base Error
        else if (error instanceof Error) {
            console.error(`[Base Error] - ${error.message}`);
        } 
        // 3. จัดการกรณีที่ throw มาเป็น String หรือค่าอื่น ๆ (ซึ่งไม่แนะนำ)
        else {
            console.error("Unknown Error type:", error);
        }
    }
}

 

C. การเข้าถึง Stack Trace

 

Stack Trace ซึ่งแสดงลำดับการเรียกฟังก์ชันที่ทำให้เกิดข้อผิดพลาด จะเป็น Property หนึ่งของ Object ที่สืบทอดจาก Error

TypeScript
try {
    throw new Error("Detailed failure.");
} catch (error) {
    if (error instanceof Error) {
        console.log(`Error Name: ${error.name}`);
        console.log(`Stack Trace:n ${error.stack}`); // เข้าถึง Stack Trace
    }
}

 

3. การใช้งาน rethrow (ส่งต่อข้อผิดพลาด)

 

ใน TypeScript เราไม่มีคีย์เวิร์ด rethrow โดยตรง แต่ใช้คีย์เวิร์ด throw ภายในบล็อก catch เพื่อโยนข้อผิดพลาดเดิมออกไปให้ Handler ที่อยู่สูงกว่า (Outer Handler) จัดการต่อ

TypeScript
function handleAndRethrow(deposit: number, withdraw: number) {
    try {
        checkWithdraw(deposit, withdraw);
    } catch (e) {
        if (e instanceof WithdrawError) {
            // ทำการบันทึกข้อผิดพลาดในระดับนี้ (Log)
            console.warn(`[Local Handler] Logged withdrawal error for user.`);
            // แล้วส่งต่อข้อผิดพลาดนี้ไปให้ Handler ภายนอก
            throw e; 
        } 
        // Error อื่น ๆ จะถูกส่งต่อโดยอัตโนมัติหากไม่ถูกจับ
    }
}

try {
    handleAndRethrow(200, 300);
} catch (e) {
    // Handler ภายนอกจะได้รับ WithdrawError ต่อจาก handleAndRethrow
    console.error(`[Global Handler] Transaction failed completely.`);
}

 

4. การใช้งาน finally

 

บล็อก finally จะทำงานเสมอ ไม่ว่าในบล็อก try จะเกิดข้อผิดพลาดหรือไม่ หรือเกิดแล้วถูกจัดการด้วย catch หรือไม่ก็ตาม มักใช้สำหรับโค้ดทำความสะอาด (Cleanup) เช่น การปิดไฟล์ หรือปิดการเชื่อมต่อฐานข้อมูล

TypeScript
function runWithCleanup() {
    let connectionStatus = 'open';
    try {
        // โค้ดที่อาจเกิด error
        console.log('Attempting operation...'); 
        // throw new Error("Connection lost"); 
        
    } catch (e) {
        console.error("Operation failed.");
    } finally {
        // โค้ดใน finally จะทำงานเสมอ
        connectionStatus = 'closed';
        console.log(`Connection is now: ${connectionStatus}`); 
    }
}

runWithCleanup();


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



ทบทวนบทความที่แล้ว









เนื้อหาที่เกี่ยวข้อง



Tags:: typescript







URL สำหรับอ้างอิง










เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ