จัดการ Error อย่างไรใน Go

Sharing is caring!

คำค้น (SEO Keywords): Golang Error, การจัดการ Error ใน Go, error handling ภาษา Go, Go panic recover, Go try catch

ทำไม Error Handling ถึงสำคัญในภาษา Go?

ภาษา Go เลือกแนวทางการจัดการ Error ที่ตรงไปตรงมา โดยหลีกเลี่ยงรูปแบบ try/catch ที่ซับซ้อน และใช้การ return error เป็นค่าหนึ่งใน function แทน

แนวทางนี้แม้จะดู “ธรรมดา” แต่กลับทำให้โค้ด Go อ่านง่าย ตรวจสอบได้ และบังคับให้ programmer ใส่ใจกับ error อย่างจริงจัง

โครงสร้างการ return error แบบพื้นฐาน

ดูตัวอย่าง function ที่ return ค่าผลลัพธ์และ error

package main

import (
    "errors"
    "fmt"
)

func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("ไม่สามารถหารด้วยศูนย์ได้")
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 0)
    if err != nil {
        fmt.Println("เกิดข้อผิดพลาด:", err)
        return
    }
    fmt.Println("ผลลัพธ์:", result)
}
  

ผลลัพธ์: โปรแกรมจะพิมพ์ข้อความ error และไม่ crash

วิธีสร้าง Error แบบกำหนดเอง

Go รองรับการสร้าง error ด้วย errors.New() หรือ fmt.Errorf() ซึ่งสามารถใส่ค่าตัวแปรได้:

err := fmt.Errorf("ไม่พบผู้ใช้งาน id = %d", userId)

ใช้ Custom Error Struct

สามารถสร้าง struct เพื่อแยกประเภท error ได้:

type NotFoundError struct {
    ID int
}

func (e NotFoundError) Error() string {
    return fmt.Sprintf("ไม่พบข้อมูลที่มี ID = %d", e.ID)
}
  

ใช้ errors.Is และ errors.As

ตั้งแต่ Go 1.13 เราสามารถใช้ errors.Is และ errors.As เพื่อเช็คประเภทของ error ได้:

if errors.As(err, &NotFoundError{}) {
    fmt.Println("เจอ NotFoundError")
}
  

การใช้ panic และ recover

panic จะทำให้โปรแกรมหยุดทำงานเหมือน throw exception แต่เราสามารถใช้ recover เพื่อกู้สถานะได้:

func risky() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("กู้จาก panic:", r)
        }
    }()
    panic("บางอย่างผิดพลาด")
}
  

แต่ควรหลีกเลี่ยงการใช้ panic ถ้าไม่จำเป็นจริง ๆ เช่นกรณี bug ภายใน library

การสร้าง Wrapper Error แบบมี stack trace

ใช้ %w ใน fmt.Errorf เพื่อ wrap error:

baseErr := errors.New("connect fail")
wrapped := fmt.Errorf("fetch user failed: %w", baseErr)

ภาพประกอบ: Error Handling ใน Go

แนวทาง Best Practices

  • ตรวจสอบ error ทันทีหลังการเรียกฟังก์ชัน
  • อย่าละเลย error ด้วย _ เว้นแต่จำเป็นจริง ๆ
  • ใช้ error wrapping เพื่อ debug ได้ง่าย
  • แยกประเภท error ด้วย custom error type
  • หลีกเลี่ยง panic เว้นแต่เป็น bug ที่ต้อง report

เทียบกับภาษาอื่น

ภาษาแนวทางจัดการ Error
Goreturn error เป็นค่าหนึ่งในฟังก์ชัน
Javatry/catch Exception
Pythonraise Exception แล้ว try/except
RustResult + match

สรุป

ภาษา Go อาจไม่มี try/catch แต่การ return error อย่างชัดเจนทำให้โปรแกรมของคุณมีความปลอดภัยสูง และอ่านง่าย การเข้าใจการใช้งาน error, wrapping, และ recover จะช่วยให้คุณเขียนระบบที่ robust และ maintain ได้ดีขึ้น


บทความโดย: poolsawat.com | เขียนโดย: King Pool

Leave a Reply

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