PlusMagi's Blog By Pitt Phunsanit Backend,Database Go Error Handling & Control Flow (รูปแบบการจัดการ Error แบบ Explicit, Panic/Recover และ Defer ใน Go)

Go Error Handling & Control Flow (รูปแบบการจัดการ Error แบบ Explicit, Panic/Recover และ Defer ใน Go)

ในโลกของการพัฒนาแอปพลิเคชันที่เชื่อมต่อกับฐานข้อมูล การจัดการข้อผิดพลาด (Error Handling) และการควบคุมการไหลของโปรแกรม (Control Flow) อย่างมีประสิทธิภาพถือเป็นหัวใจสำคัญที่ทำให้ระบบมีความเสถียรและเชื่อถือได้

เมื่อเราใช้ภาษา Go (Golang) ในการเชื่อมต่อและจัดการข้อมูลกับฐานข้อมูล PostgreSQL การทำความเข้าใจกลไกการจัดการข้อผิดพลาดที่ถูกต้องตามหลักการ (Idiomatic Go) จึงเป็นสิ่งจำเป็น บทความนี้จะเจาะลึกถึงการจัดการข้อผิดพลาดทั้งสามรูปแบบ: การจัดการแบบชัดเจน (Explicit), การใช้ Panic/Recover, และการใช้ Defer โดยเน้นการนำไปประยุกต์ใช้ในบริบทของการทำงานกับ PostgreSQL

🟢 1. Explicit Error Handling: แนวทางที่ถูกหลักการที่สุด (The Idiomatic Way)

นี่คือกลไกหลักที่ควรใช้ในการเขียนโค้ด Go ที่ทำงานกับ PostgreSQL โดยทั่วไปแทนที่จะปล่อยให้เกิดข้อผิดพลาดแบบล้มเหลว (Crash) เราต้องตรวจสอบค่าข้อผิดพลาด (error value) ที่ส่งกลับมาจากการเรียกใช้คำสั่ง SQL เสมอ

ในระดับ PostgreSQL เอง การจัดการข้อผิดพลาดที่ชัดเจนทำได้โดยการใช้คำสั่งควบคุม Flow เช่น `RAISE EXCEPTION` เพื่อให้ Stored Procedure หรือ Function สามารถแจ้งข้อผิดพลาดที่เฉพาะเจาะจงกลับไปยังแอปพลิเคชันที่เรียกใช้ได้

ตัวอย่างการจัดการข้อผิดพลาดใน PostgreSQL (PL/pgSQL)

SQL

-- การตรวจสอบเงื่อนไขและแจ้งข้อผิดพลาดอย่างชัดเจน (Explicit Error) --
CREATE OR REPLACE FUNCTION process_data(p_input text) RETURNS void AS $$
BEGIN
    IF p_input IS NULL OR p_input = '' THEN
        -- ใช้ RAISE EXCEPTION เพื่อส่งข้อผิดพลาดที่กำหนดเอง
        RAISE EXCEPTION 'Input data cannot be empty.';
    END IF;
    
    -- หากผ่านการตรวจสอบ จะดำเนินการต่อ
    INSERT INTO data_table (data_list) VALUES (p_input);
END;$$ LANGUAGE plpgsql;

-- การเรียกใช้ฟังก์ชันและจัดการข้อผิดพลาดที่คาดหวัง
SELECT process_data('apple,banana,orange');
-- หากเรียกด้วยค่าว่าง จะเกิดข้อผิดพลาดที่ถูกดักจับได้
-- SELECT process_data('');

💥 2. Panic/Recover: สำหรับสถานการณ์วิกฤต (Catastrophic Failure)

กลไกนี้ใช้สำหรับสถานการณ์ที่ระบบอยู่ในภาวะวิกฤตและไม่สามารถดำเนินการต่อไปได้ (เช่น การเชื่อมต่อฐานข้อมูลขาดหายโดยไม่คาดคิด) ซึ่งเป็นข้อผิดพลาดที่รุนแรงกว่าการจัดการข้อผิดพลาดทั่วไป การใช้ `panic` ใน Go ควรสงวนไว้สำหรับกรณีเหล่านี้เท่านั้น

ใน PostgreSQL (PL/pgSQL) เราใช้บล็อก `EXCEPTION` ซึ่งทำหน้าที่คล้ายกับการ `recover` เพื่อดักจับข้อผิดพลาดที่รุนแรงและดำเนินการ Rollback Transaction เพื่อให้ระบบกลับสู่สถานะก่อนเกิดเหตุการณ์

SQL

-- การใช้ EXCEPTION block เพื่อดักจับข้อผิดพลาดรุนแรง
BEGIN
    -- สมมติว่าโค้ดส่วนนี้อาจเกิดข้อผิดพลาดร้ายแรง
    PERFORM 1 / 0;
EXCEPTION
    WHEN division_by_zero THEN
        -- ทำการ Rollback และบันทึกเหตุการณ์วิกฤต
        RAISE NOTICE 'Caught critical error: Division by zero. Rolling back transaction.';
        ROLLBACK;
END;

🧹 3. Defer: การทำความสะอาดทรัพยากร (Resource Cleanup)

คำสั่ง `defer` ใน Go มีหน้าที่รับประกันว่าโค้ดบางส่วนจะถูกเรียกใช้เสมอ ไม่ว่าฟังก์ชันจะจบลงด้วยการสำเร็จหรือการเกิดข้อผิดพลาดก็ตาม ในบริบทของ PostgreSQL สิ่งนี้เทียบเท่ากับการจัดการ Transaction (Transaction Management) ซึ่งรับประกันว่าทรัพยากรจะถูกปล่อยหรือสถานะจะถูกย้อนกลับ

การใช้ `BEGIN…COMMIT…ROLLBACK` คือการจำลองหลักการของ `defer` เพื่อให้แน่ใจว่าการล็อก (Locks) หรือการเปลี่ยนแปลงข้อมูลจะถูกจัดการอย่างสมบูรณ์

SQL

-- การใช้ Transaction เพื่อรับประกันการทำความสะอาด (Cleanup) --
BEGIN;
    -- 1. ทำการเปลี่ยนแปลงข้อมูล (Work)
    INSERT INTO audit_log (action) VALUES ('Transaction started');
    
    -- 2. ใช้ DEFERRAL (COMMIT/ROLLBACK) เพื่อรับประกันการทำความสะอาด
    -- หากเกิดข้อผิดพลาดใดๆ ในระหว่างนี้ COMMIT จะไม่ถูกเรียกใช้
    -- และระบบจะทำการ ROLLBACK โดยอัตโนมัติ
    COMMIT;
EXCEPTION
    WHEN others THEN
        -- หากมีข้อผิดพลาด จะทำการ Rollback ทันที
        ROLLBACK;
        RAISE EXCEPTION 'Transaction failed and rolled back.';
END;

✅ บทสรุป: การเขียนโค้ดที่แข็งแกร่งด้วยหลักการ Go

การเขียนโค้ดที่แข็งแกร่งและเป็นไปตามหลักการ (Idiomatic) คือการให้ความสำคัญกับการจัดการข้อผิดพลาดแบบ Explicit เป็นอันดับแรกเสมอ ควรใช้ `panic`/`recover` และ `defer` เฉพาะในสถานการณ์ที่จำเป็นจริง ๆ เท่านั้น

การทำความเข้าใจกลไกเหล่านี้ช่วยให้เราสามารถสร้างแอปพลิเคชันที่เชื่อมต่อกับ PostgreSQL ได้อย่างเสถียร ทราบว่าเมื่อใดควรตรวจสอบค่าข้อผิดพลาด, เมื่อใดควร Rollback ทรัพยากร, และเมื่อใดที่ระบบจำเป็นต้องหยุดการทำงานอย่างสง่างาม

Exit mobile version