Skip to main content

Error กับ Go

เราจัดการ Error ใน go ยังไง ?

โดยปกติ ถ้าเป็นหลายภาษาที่เราคุ้นเคย เราจะใช้ try catch ในการ handle error กัน

  • ซึ่งในภาษา Go ไม่มีสิ่งนี้
  • แต่แทนสิ่งนี้ด้วยการ return value ของสิ่งที่บ่งบอกว่าจะเป็น error ออกมาแทน เพื่อให้เรียกใช้งานได้อย่างเรียบง่าย และสามารถส่งข้อมูล error ออกมาบอกได้เวลาที่มันเกิดขึ้น

Concept หลักของการจัดการ Error Handling ใน Go

  1. go จะมี type อีกหนึ่งประเภทคือ error ซึ่งสามารถเรียกใช้งานผ่านคำสั่ง Error() ได้และทำการ return เป็น String ออกมาได้
  2. การ return function นั้น โดย default ของ go จะทำการคืนค่าออกเป็น 2 ตัวคือ result, error
  • result = ผลลัพธ์ของ function
  • error = ค่าของ Error ที่เกิดขึืน (เมื่อมี Error เกิดขึ้น)
  1. การ check Error = สามารถทำได้จาก variable หลังจาก return function ออกมา
  • โดยทั่วไป ถ้าไม่มี error ออกมา = จะได้ค่าเป็น nil (ก็คือ null ใน go)
  • ถ้ามี error ก็จะไม่เป็น nil และมีผลของการ Error ออกมาได้

เรามาลองดูตัวอย่างผ่าน code กัน

Example error code

ท่าปกติ

เคสแรก เราจะมาลองทำ function divide สำหรับการเลขกัน โดย

  • ถ้าใส่เลขตัวหารเป็น 0 (b = 0) มาจะต้อง Error เพื่อป้องกัน runtime error ที่ส่งผลทำให้ application crash ได้
  • เราจึงเพิ่มการ return ตัว error กลับออกไปคู่กัน (การ return ก็จะเป็นการใส่ error คู่กับผลลัพธ์ไว้)
package main

import (
"errors"
"fmt"
)

// divide divides two integers and returns an error if the divisor is 0
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}

func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}

ผลลัพธ์ go-control-01

ท่า Custom Error

จริงๆแล้วภาษา go มีการ implement ตัว interface error เอาไว้หน้าตาประมาณนี้

type error interface {
Error() string
}

เพราะฉะนั้น หากต้องการ implement error อะไรออกมาผ่าน interface ของ error = ทำการสร้าง method Error() ก็จะสามารถทำการคืนค่าแบบเดียวกันกับ error ออกไปได้

เช่น code นี้

  • เรามาลองทำตัว check login ดูโดยทำการรับ user, pass มา
  • ถ้าเกิด error = ให้ทำการบอก error กลับไป
  • อันนี้เป็นอีกหนึ่งวิธีที่ใช้กันเช่นกันคือ การคืน error ออกมาจาก result ของ function เลย
package main

import (
"fmt"
)

// LoginError is a custom error type for login failures
type LoginError struct {
Username string
Message string
}

// Implement the Error() method to satisfy the error interface
func (e *LoginError) Error() string {
return fmt.Sprintf("Login error for user '%s': %s", e.Username, e.Message)
}

// Simulated function that attempts a user login
func login(username, password string) error {
// Simulate checking username and password
if username != "admin" || password != "password123" {
return &LoginError{Username: username, Message: "invalid credentials"}
}
// Login successful
return nil
}

func main() {
// Attempt to login with wrong credentials
err := login("user", "pass")
if err != nil {
switch e := err.(type) {
case *LoginError:
// Custom error handling
fmt.Println("Custom error occurred:", e)
default:
// Other types of errors
fmt.Println("Generic error occurred:", e)
}
return
}

// Continue with the rest of the program if login is successful
fmt.Println("Login successful!")
}

** จริงๆแล้วการ handle error มันจะมีอีกหลากหลายวิธีที่อำนวยความสะดวกในการ tracing error อย่างมาก

เราจะมาค่อยๆเรียนรู้จากการทำ Application จริงกัน

และนี่ก็คือ Basic programming และพื้นฐานทั้งหมดที่ควรรู้ของภาษา Go

Session ต่อไปเราจะเริ่มเข้าสู่ Application Level กันว่า ในการทำ Application เช่นการทำ API ออกมาสามารถทำออกมารูปแบบไหนได้บ้าง และการประยุกต์ใช้สิ่งเหล่านี้กับ Application สามารถทำยังไงได้บ้าง

เจอกันใน Session ต่อไป