Go – Xử lý lỗi

error-handling

Go không cung cấp phương thức try/catch như thông thường để xử lý lỗi, thay vào đó các lỗi được trả về như một giá trị.

Chúng ta đều hiểu rằng lỗi là một cái gì đó bất thường xảy ra trong chương trình, nhưng trong Go lỗi có một ý nghĩa khác. Lỗi chỉ là một giá trị hàm có thể trả về nếu có điều gì đó không mong đợi xảy ra.

error được tích hợp sẵn trong Go với giá trị mặc định là nil. Có một cách để xử lý lỗi là trả về nó như giá trị cuối cùng của hàm gọi và kiểm tra xem nó có nil hay không.

Kiểu error

Hãy cùng tìm hiểu sâu hơn về kiểu dữ liệu error. error là kiểu tích hợp sẵn nhưng thực tế nó là một kiểu interface có sẵn, sử dụng ở mọi nơi trong chương trình Go, và nó thực thi phương thức Error() trả về một thông báo lỗi dạng string

Do đó chúng ta có thể định nghĩa các kiểu dữ liệu lỗi bằng cách thực thi cho error interface. Hãy cùng xem ví dụ sau đây

Kết quả

Trong ví dụ bên trên, chúng ta đã tạo kiểu struct MyError, cung cấp thực thi code cho phương thức Error. Phương thức này trả về một string. Do đó, struct MyError đã thực thi code cho interface error.

Nhưng để tạo ngay cả một error đơn giản, chúng ta cũng phải định nghĩa một struct và tạo một thực thi code cho phương thức Error(). Để tránh điều này, Go cung cấp một package error được tích hợp sẵn, và public hàm New. Hàm này yêu cầu một thông báo lỗi và trả về error.

Kết quả

Chúng ta có thể thấy rằng hàm New yêu cầu một string, là thông báo lỗi, và trả về một error. Chúng ta cũng hiểu rằng lỗi trả về là kiểu gì đấy thực thi code cho interface error, vấy myError là kiểu gì? Hãy viết lại ví dụ bên trên và thử in ra kiểu trả về.

Kết quả

Như vậy kiểu dữ liệu của myErr*errors.errorString, nó là một con trỏ cho errors.errorString.

Package error có struct errorString thực thi code cho error interface.

Hàm New tạo và trả về con trỏ cho struct errorString.

Trích xuất thêm thông tin về lỗi

Trong các ví dụ trước, chúng ta chỉ in ra các thông báo lỗi. Giả sử chúng ta viết một chương trình để mở một file text và chúng ta muốn biết đường dẫn thực sự gây ra lỗi. Có một cách đó là phân tích thông tin lỗi.

Chúng ta có thể phân tích thông báo lỗi và thấy được đường dẫn là /text.txt, nhưng đây không phải là một cách tốt bởi vì thông tin của thông báo có thể thay đổi bất kỳ lúc nào khi ngôn ngữ cập nhập phiên bản mới và code của chúng ta sẽ bị lỗi.

Lấy thêm thông tin từ các trường của struct

Nếu bạn đọc kỹ tài liệu về hàm Open, bạn sẽ thấy kiểu trả về của lỗi là *PathError. PathError là kiểu struct và phần thực thi code của nó như sau:

*PathError thực thi code cho error interface bằng cách khai báo phương thức Error() string. Phương thức này trả về thông tin hoạt động (op), đường dẫn (path), và lỗi (error) nối liên tiếp với nhau. Cuối cùng, chúng ta có thông tin lỗi như sau

Trường path của struct PathError chứa đường dẫn file bị lỗi.  Hãy cùng xem ví dụ sau

Kết quả

Trong ví dụ trên chúng ta thực hiện kiểm tra lỗi ở hàng 10 và lấy được giá trị của interface error, và sau đó chúng ta in ra thông tin đường dẫn lỗi bằng cách gọi err.path.

Lấy thêm thông tin sử dụng phương thức

Cách thứ 2 để lấy thêm thông tin về lỗi là gọi các phương thức trên kiểu struct. Để hiểu rõ hơn chúng ta cùng xem ví dụ sau

Kiểu struct DNSError trong chuẩn thư viện được định nghĩa như sau

Như bạn đã thấy đoạn code bên trên, struct DNSError có 2 phương thức Timeout() bool và Temporary() bool trả về giá trị boolean để chỉ định rằng lỗi là do không nhận được phản hồi (timeout) hoặc là tạm thời (temporary).

Nào hãy cùng xem ví dụ sau

Trong ví dụ trên chúng ta thử lấy địa chỉ IP của domain không tồn tại vngeeks123.com.  Để kiểm tra chúng ta thử lấy thông tin khi lỗi xảy ta bằng cách sử dụng *net.DNSError, sau đó thử kiểm tra xem lỗi là do timeout hay là temporary.

Trong trường hợp của chúng ta đều không phải do Timeout hay Temporary nên kết quả trả về là

Đừng bỏ qua các lỗi

Không nên bỏ qua lỗi. Bỏ qua các lỗi là tăng thêm rắc rối cho chương trình. Hãy thử viết một chương trình lấy danh sách các thư mục và bỏ qua việc xử lý lỗi

Chương trình sẽ đưa ra một lỗi vì pattern là không hợp lệ. Đoạn code đã bỏ qua lỗi bằng cách sử dụng  gạch dưới _. Tiếp theo thực hiện ra danh sách các file.

Kết quả

Do chúng ta bỏ qua lỗi, kết quả dường như là không có file nào phù hợp với pattern, nhưng thực tế là do pattern không hợp lệ. Nên sẽ gây khó khăn cho việc nhận biết lỗi, do đó chúng ta không nên bỏ qua lỗi.

 

 

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

avatar
  Subscribe  
Notify of