PlusMagi's Blog By Pitt Phunsanit Backend,Database Rust Error Handling: การจัดการ Recoverable Errors ด้วย Result และ Unrecoverable ด้วย panic!

Rust Error Handling: การจัดการ Recoverable Errors ด้วย Result และ Unrecoverable ด้วย panic!

ในโลกของการพัฒนาซอฟต์แวร์ระดับองค์กร ความท้าทายไม่ได้อยู่ที่การทำให้โค้ดทำงานได้เท่านั้น แต่อยู่ที่การออกแบบให้มัน “ไม่ล้มเหลว” (Fail-safe) การจัดการกับสถานการณ์ผิดพลาด (Error Handling) จึงเป็นหัวใจสำคัญที่กำหนดความน่าเชื่อถือและความแข็งแกร่งของโปรแกรม

แม้ว่าภาษา Rust จะใช้แนวคิด `Result` เพื่อบังคับให้ผู้พัฒนาต้องพิจารณาทุกเส้นทางที่เป็นไปได้ แต่หลักการนี้สามารถนำมาเปรียบเทียบกับระบบฐานข้อมูลที่แข็งแกร่งอย่าง PostgreSQL ได้อย่างยอดเยี่ยม โดยเราสามารถมองว่าการจัดการข้อผิดพลาดใน PostgreSQL คือการแยกความแตกต่างระหว่าง “ข้อผิดพลาดที่สามารถกู้คืนได้” (Recoverable Errors) และ “ข้อผิดพลาดร้ายแรงที่ไม่สามารถกู้คืนได้” (Unrecoverable Errors) ซึ่งเป็นหัวใจของการออกแบบ Transaction ที่สมบูรณ์

Result ในมุมมองของ PostgreSQL: การจัดการ Recoverable Errors

สำหรับข้อผิดพลาดที่สามารถคาดการณ์และจัดการได้ (เช่น การป้อนข้อมูลผิดรูปแบบ, การพยายามอัปเดตแถวที่ไม่มีอยู่, หรือการละเมิด Unique Constraint) PostgreSQL ใช้กลไกของ Transaction และ Error Codes เฉพาะเจาะจง ซึ่งเทียบได้กับ `Result` ใน Rust

เมื่อเราใช้ Transaction เรากำลังกำหนดขอบเขตที่ชัดเจนว่าการดำเนินการใดควรสำเร็จ (Commit) และการดำเนินการใดควรล้มเหลว (Rollback) ระบบจะส่งคืน Error Code ที่เฉพาะเจาะจง ทำให้เราสามารถเขียนโค้ดเพื่อดักจับและจัดการกับสถานะล้มเหลวเหล่านั้นได้อย่างแม่นยำ

ตัวอย่างการจัดการ Recoverable Error ด้วย Transaction:

SQL

BEGIN;</code><pre><code class="language-sql">-- พยายามแทรกข้อมูลที่ละเมิด Unique Constraint</code><pre><code class="language-sql">INSERT INTO products (product_id, name) VALUES (1, 'apple');</code><pre><code class="language-sql">-- คำสั่งนี้จะล้มเหลวเพราะ product_id 1 มีอยู่แล้ว (Recoverable Error)</code><pre><code class="language-sql">INSERT INTO products (product_id, name) VALUES (1, 'banana');</code><pre><code class="language-sql">-- หากเกิดข้อผิดพลาด จะต้อง Rollback เพื่อรักษาความสมบูรณ์ของข้อมูล</code><pre><code class="language-sql">ROLLBACK;

การใช้คำสั่ง `ROLLBACK` คือการจัดการสถานะล้มเหลวที่คาดการณ์ได้ ทำให้มั่นใจได้ว่าฐานข้อมูลจะอยู่ในสถานะที่สอดคล้องกับก่อนเริ่ม Transaction เสมอ

Unrecoverable Errors: เมื่อระบบล้มเหลวโดยสิ้นเชิง

ในทางตรงกันข้ามกับ `Result` ที่จัดการความผิดพลาดระดับแอปพลิเคชัน (Application Layer) ข้อผิดพลาดที่ไม่สามารถกู้คืนได้ (Unrecoverable Errors) ใน PostgreSQL มักเกิดจากปัญหาในระดับระบบ (System Layer) เช่น การสูญเสียการเชื่อมต่อเครือข่ายอย่างกะทันหัน (Connection Loss), การล่มของเซิร์ฟเวอร์, หรือการที่ Schema ของฐานข้อมูลเสียหายอย่างรุนแรง

ในสถานการณ์เหล่านี้ ไม่ใช่แค่ `ROLLBACK` จะเพียงพอ แต่แอปพลิเคชันที่เรียกใช้จะต้องถูกออกแบบให้สามารถตรวจจับการขาดการเชื่อมต่อและพยายามเชื่อมต่อใหม่ได้ (Retry Mechanism) ซึ่งเป็นแนวคิดที่อยู่เหนือการจัดการ Transaction ทั่วไป

บทสรุป: สถาปัตยกรรมที่แข็งแกร่ง

ไม่ว่าจะเป็นการใช้ `Result` ใน Rust หรือการใช้ Transaction และ Error Handling ใน PostgreSQL หลักการทางสถาปัตยกรรมยังคงเหมือนเดิม นั่นคือการออกแบบระบบที่คาดการณ์และจัดการกับความล้มเหลวที่อาจเกิดขึ้นได้อย่างเป็นระบบ การแยกแยะระหว่างข้อผิดพลาดที่สามารถกู้คืนได้ (ที่ใช้ `ROLLBACK`) และข้อผิดพลาดร้ายแรง (ที่ต้องมีการเชื่อมต่อใหม่) คือกุญแจสำคัญในการสร้างระบบที่น่าเชื่อถือในระดับองค์กร