☰ Mục lục series
Tài liệu Go tiếng Việt
  1. Bắt đầu (Getting started)
    1. Tổng quan
    2. Tải về và cài đặt
    3. Bắt đầu với Go
    4. Quản lý các bản cài đặt Go
    5. Plugin trình soạn thảo và IDE
  2. Dạo quanh Go (A Tour of Go)
    1. Chào mừng
    2. Package, biến và hàm
    3. Điều khiển luồng
    4. Struct, slice và map
    5. Method và interface
    6. Generics
    7. Xử lý đồng thời
  3. Hướng dẫn (Tutorials)
    1. Danh sách hướng dẫn
    2. Tạo một Go module
    3. Gọi mã của bạn từ một module khác
    4. Trả về và xử lý lỗi
    5. Trả về lời chào ngẫu nhiên
    6. Trả về lời chào cho nhiều người
    7. Thêm một test
    8. Biên dịch và cài đặt ứng dụng
    9. Kết luận
    10. Bắt đầu với workspace nhiều module
    11. Phát triển RESTful API với Go và Gin
    12. Truy cập cơ sở dữ liệu quan hệ
    13. Bắt đầu với generics
    14. Bắt đầu với fuzzing
    15. Làm việc với JSON
    16. Tìm và sửa các dependency có lỗ hổng với govulncheck
    17. Tìm và khắc phục phụ thuộc có lỗ hổng với VS Code Go
    18. Viết ứng dụng web
  4. Viết code Go
    1. Cách viết mã Go
    2. Effective Go
    3. Doc Comment trong Go
  5. Module
    1. Phát triển và publish module
    2. Quản lý phụ thuộc
    3. Tổ chức một module Go
    4. Quản lý mã nguồn của module
    5. Cách đánh số phiên bản module
    6. Quy trình phát hành và đánh phiên bản module
    7. Publish một module
    8. Phát triển một bản cập nhật major version
    9. Tham chiếu tệp go.mod
    10. Ngừng hỗ trợ 'go get' cho việc cài đặt tệp thực thi
  6. Cơ sở dữ liệu (Database)
    1. Truy cập cơ sở dữ liệu quan hệ
    2. Mở một handle cơ sở dữ liệu
    3. Thực thi câu lệnh SQL không trả về dữ liệu
    4. Truy vấn dữ liệu
    5. Dùng prepared statement
    6. Thực thi transaction
    7. Huỷ các thao tác đang chạy
    8. Quản lý kết nối
    9. Tránh rủi ro SQL injection
  7. Chẩn đoán và hiệu năng
    1. Chẩn đoán
    2. Hướng dẫn về Go Garbage Collector
    3. Tối ưu hoá dựa trên profile
    4. Data Race Detector
    5. Gỡ lỗi mã Go bằng GDB
    6. Hỗ trợ coverage profiling cho integration test
  8. Bảo mật (Security)
    1. Tổng quan bảo mật
    2. Thực hành tốt về bảo mật cho lập trình viên Go
    3. Quản lý lỗ hổng trong Go
    4. Cơ sở dữ liệu lỗ hổng của Go
    5. Quét lỗ hổng trong IDE
    6. Chính sách CNA của Go
    7. Go Fuzzing
    8. Chi tiết kỹ thuật của Go Fuzzing
    9. Chính sách bảo mật của Go
    10. Threat Model của Go
    11. Các quyết định về bảo mật của Go
    12. Tuân thủ FIPS 140-3
  9. Công cụ và toolchain
    1. Tài liệu về các lệnh
    2. Về lệnh go
    3. Go Toolchains
    4. Telemetry của Go
    5. Cài đặt Go từ mã nguồn
    6. Cài đặt và sử dụng gccgo
  10. Tham khảo
    1. Câu hỏi thường gặp (FAQ)
    2. Go 1 và tương lai của các chương trình Go
    3. Hướng dẫn chuyển đổi sang encoding/json/v2
    4. Hướng dẫn đóng góp
    5. Đóng góp cho frontend gccgo
  11. Phụ lục
    1. Bảng thuật ngữ
Hướng dẫn (Tutorials)

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

Bản dịch từ go.dev/doc/tutorial/handle-errors

Xử lý lỗi là một tính năng thiết yếu của mã nguồn vững chắc. 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ý lỗi đó ở phía gọi.

Lưu ý: Chủ đề này là một phần của loạt hướng dẫn nhiều phần, bắt đầu từ Tạo một Go module.

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

    Sẽ chẳng có ý nghĩa gì khi gửi lại một lời chào nếu bạn không biết phải chào ai. Hãy trả về lỗi cho phía gọi nếu tên rỗng. Chép đoạn mã sau vào greetings.go và lưu tệp lại.

    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. Phía 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ị. Tìm hiểu thêm tại Effective Go.)
    • Import package errors của thư viện chuẩn Go để bạn có thể dùng hàm errors.New.
    • Thêm câu lệnh if để kiểm tra yêu cầu không hợp lệ (chuỗi rỗng ở vị trí đáng lẽ phải là tên) 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 điệp của bạn bên trong.
    • Thêm nil (nghĩa là không có lỗi) làm giá trị thứ hai trong trường hợp trả về thành công. Nhờ vậy, phía gọi biết được rằng hàm đã chạy thành công.
  2. Trong tệp hello/hello.go, hãy xử lý lỗi mà hàm Hello giờ đây trả về, cùng với giá trị không phải 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 package log để in tên lệnh (“greetings: “) ở đầu mỗi thông điệp log, không kèm dấu thời gian hay 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 biến.
    • Đổi đối số của Hello từ tên Gladys thành chuỗi rỗng, để bạn thử được phần mã xử lý lỗi.
    • Kiểm tra xem giá trị error có khác nil không. Trong trường hợp này thì không có lý do gì để chạy tiếp.
    • Dùng các hàm trong package log của thư viện chuẩn để xuất thông tin lỗi. Nếu gặp lỗi, bạn dùng hàm Fatal của package log để in lỗi ra 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ây giờ bạn 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 dụng trong Go: Trả về lỗi như một giá trị để phía gọi có thể kiểm tra.

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

Nội dung gốc: Go Documentation © The Go Authors, giấy phép CC BY 3.0. Bản dịch và ghi chú: Lê Văn Dũng.