Trả về và xử lý lỗi

Xử lý lỗi là một tính năng thiết yếu của mã chất lượng. Trong phần này, bạn sẽ thêm một chút mã để trả về lỗi từ module greetings, rồi xử lý nó trong phần gọi hàm.

  1. Trong greetings/greetings.go, thêm đoạn mã được đánh dấu bên dưới.

    Không có lý do gì để gửi lời chào lại nếu bạn không biết phải chào ai. Trả về lỗi cho người gọi nếu tên bị rỗng. Sao chép đoạn mã sau vào greetings.go và lưu tệp.

    package greetings
    
    import (
        "errors"
        "fmt"
    )
    
    // Hello returns a greeting for the named person.
    func Hello(name string) (string, error) {
        // If no name was given, return an error with a message.
        if name == "" {
            return "", errors.New("empty name")
        }
    
        // If a name was received, return a value that embeds the name
        // in a greeting message.
        message := fmt.Sprintf("Hi, %v. Welcome!", name)
        return message, nil
    }
    

    Trong đoạn mã này, bạn:

    • Thay đổi hàm để nó trả về hai giá trị: một string và một error. Người gọi sẽ kiểm tra giá trị thứ hai để xem có lỗi xảy ra hay không. (Bất kỳ hàm Go nào cũng có thể trả về nhiều giá trị. Để biết thêm, xem Effective Go.)
    • Import gói errors từ thư viện chuẩn của Go để bạn có thể dùng hàm errors.New của nó.
    • Thêm câu lệnh if để kiểm tra yêu cầu không hợp lệ (một chuỗi rỗng ở nơi tên phải có) và trả về lỗi nếu yêu cầu không hợp lệ. Hàm errors.New trả về một error chứa thông báo của bạn.
    • Thêm nil (nghĩa là không có lỗi) làm giá trị thứ hai trong lần trả về thành công. Như vậy, người gọi có thể thấy rằng hàm đã thực hiện thành công.
  2. Trong tệp hello/hello.go của bạn, xử lý lỗi được trả về bởi hàm Hello, cùng với giá trị không lỗi.

    Dán đoạn mã sau vào hello.go.

    package main
    
    import (
        "fmt"
        "log"
    
        "example.com/greetings"
    )
    
    func main() {
        // Set properties of the predefined Logger, including
        // the log entry prefix and a flag to disable printing
        // the time, source file, and line number.
        log.SetPrefix("greetings: ")
        log.SetFlags(0)
    
        // Request a greeting message.
        message, err := greetings.Hello("")
        // If an error was returned, print it to the console and
        // exit the program.
        if err != nil {
            log.Fatal(err)
        }
    
        // If no error was returned, print the returned message
        // to the console.
        fmt.Println(message)
    }
    

    Trong đoạn mã này, bạn:

    • Cấu hình gói log để in tên lệnh ("greetings: ") ở đầu các thông báo log, không có nhãn thời gian hoặc thông tin tệp nguồn.
    • Gán cả hai giá trị trả về của Hello, bao gồm cả error, vào các biến.
    • Thay đổi đối số Hello từ tên của Gladys thành một chuỗi rỗng, để bạn có thể thử mã xử lý lỗi của mình.
    • Tìm kiếm giá trị error khác nil. Không có lý do gì để tiếp tục trong trường hợp này.
    • Dùng các hàm trong log package của thư viện chuẩn để xuất thông tin lỗi. Nếu bạn gặp lỗi, bạn dùng hàm Fatal của gói log để in lỗi và dừng chương trình.
  3. Tại dòng lệnh trong thư mục hello, chạy hello.go để xác nhận mã hoạt động.

    Vì bạn đang truyền vào một tên rỗng, bạn sẽ nhận được lỗi.

    $ go run .
    greetings: empty name
    exit status 1
    

Đó là cách xử lý lỗi thông thường trong Go: Trả về lỗi như một giá trị để người gọi có thể kiểm tra nó.

Tiếp theo, bạn sẽ dùng một slice trong Go để trả về một lời chào được chọn ngẫu nhiên.