CÁC LỖI KHI CODE CẦN TRÁNH CHO LẬP TRÌNH VIÊN

05/05/2021 224
LOI
CODEWELL

Với vai trò là một lập trình viên, việc làm thế nào để code sạch, code ít bug luôn là mục tiêu trong khi làm dự án. Dĩ nhiên, việc mắc lỗi và học tập từ lỗi khi code cũng không thể tránh khỏi. Nhưng hãy cùng điểm qua một số lỗi khi code mà lập trình viên có thể tránh được thông qua bài viết sau nhé!

 

1. LỖI KHI CODE: Viết try catch mà không có log

 

Khi viết code, hầu hết các bạn đều biết đến việc dùng try catch và trong catch sẽ trả về một mã lỗi hay một message lỗi.
Điều này rất tốt vs người dùng vì việc hiện ra một message lỗi sẽ thân thiện hơn rất nhiều so với việc không thông báo gì hay báo một message “lỗi hệ thống”. Nhưng tới đây chúng ta mới chỉ làm được một nửa việc cần làm.

Việc còn lại chính là làm thế nào để biết được khi có lỗi xảy ra? (khi người dùng thấy lỗi họ có thể phản hồi hoặc không)
Nếu biết có lỗi thì làm thế nào để biết được đó là lỗi gì? Điều tra như thế nào?

Vì vậy, việc các bạn viết try catch sẽ trở nên rất nguy hiểm nếu bạn không viết log. Khi lỗi xảy ra không ai biết được, và khó có thể điều tra đó là lỗi gì; đây là lý do mà các bạn cần viết log trong catch.

Ví dụ mẫu: KHÔNG NÊN:

try {

// ABC

return true

} catch (\Exception $e) {

return false

}

=> Nên:

try {

// ABC

return true

} catch (\Exception $ex) {

Log::error(“PREFIX” . __FILE__ . “:” .  __LINE__ . ” ERROR : ” . $ex);

return false

}

Chú ý: viết log càng chi tiết thì việc điều tra lỗi khi code càng nhanh. Có một vài chú ý khi viết log trong catch như sau:

  • Sử dụng log level error không trên product sẽ khi config log level là error, khi đó, các log debug hay info sẽ không có trong log.
  • Nên có PREFIX, yếu tố này sẽ dễ dàng cho bạn biết lỗi thuộc chức năng nào.
  • Phải có nội dung lỗi $ex. Nếu không có nội dung này thì việc log của bạn sẽ chỉ đạt được 30% mục tiêu.
  • Nếu được, bạn nên log thêm cả file và line để việc điều tra và debug sẽ nhanh hơn.

 

2. LỖI KHI sử dụng Transaction

Trong phần này, chúng ta cùng thảo luận khi nào và tại sao chúng ta cần dùng/ không cần dùng Transaction.

2.1. Tại sao cần dùng Transaction

Giả sử bạn có 2 bảng trong database và 2 bảng này có ràng buộc với nhau.
Một bảng member và một bảng member_detail. Khi tạo một member các bạn sẽ tạo ra data trong bảng member rồi tạo data trong bảng member_detail.
Sẽ ra sao nếu các bạn tạo xong data trong bảng member, tuy nhiên khi tạo data cho bảng member_detail bị lỗi?

=> Lúc này tính toàn vẹn data của bạn không đảm bảo và bạn bị mất data.

Vì thế, trong trường hợp này, việc dùng Transaction sẽ giúp đảm bảo tính toàn vẹn của một phiên giao dịch.

Việc này cũng sẽ tương tự như tại ngân hàng, nếu chuyển tiền từ anh A sang anh B nhưng không đảm bảo tính toàn vẹn của một phiên giao dịch sẽ có trường hợp tiền chuyển sang bên B rồi, nhưng lại chưa kịp trừ bên A.

2.2 Khi nào cần dùng Transaction?

Như đã nói ở trên, khi trong một phiên giao dịch các bạn tác động vào từ 2 bảng trở lên, các bạn bắt buộc phải dùng Transaction.
Ngược lại, khi chỉ tác động vào một bảng hay khi những xử lý chỉ là get data chứ ko làm thay đổi data thì sử dụng Transaction sẽ là không cần thiết.
Vì khi dùng Transaction, hệ thống sẽ có khoảng thời gian lock database gây chậm, nên các bạn phải hiểu rõ khi nào cần dùng và khi nào thì không.

Lý thuyết là như vậy, nhưng nếu chúng ta có bài toán như sau:
Khi thanh toán tiền online và dùng API của bên thứ 3, sau đó hệ thống nội bộ cần update việc thanh toán này vào một bảng thì sao? Trường hợp này có cần dùng Transaction không?
Theo lý thuyết trên thì chúng ta chỉ thao tác trên một bảng data nên không cần dùng. Tuy nhiên, ở bài toán này bạn nên dùng.
Đầu tiên, bạn cần hiểu phiên giao dich ở đây là gì?
Ta cần gọi API thanh toán sang bên thứ 3 đồng thời cần update database nội bộ, vì vậy rõ ràng 2 quá trình này cần đảm bảo tính toàn vẹn và đó là một phiên giao dịch.

Ở bài toán trên có thể nhiều bạn sẽ làm như sau:

Gọi API thanh toán xong update database nội bộ => NG
=> Các bạn nghĩ sao khi update database nội bộ bị NG trong khi API đã trừ tiền của khách hàng? Bạn gọi lại API để cancel thanh toán trên mà việc thao tác API bên thứ 3 là rủi ro hơn so vs việc xử lý nội bộ.

Lời khuyên là các bạn nên làm ngược lại:
Start một Transaction
=> insert thông tin cần thiết vào database của mình
lúc này gọi API
=> nếu API thành công => commit
=> nếu API thất bại => bạn chỉ cần rollback là OK

 

3. LỖI KHI CODE: Việc lấy data / update / tạo mới mà không check sự ràng buộc

Ví dụ các bạn có bảng orders một sản phẩm như sau trong đó id là PK
| id | customer_id | product_id | …

Khi thực hiện lấy thông tin detail hay update cũng như delete một order nào đó của một khách hàng, hầu hết các bạn chỉ quan tâm đến orders#id.

Nếu như chạy bình thường thì không sao, nhưng một ngày, có ai đó muốn thử hệ thống của bạn, họ biết orders#id của mình, họ sửa giá trị orders#id của mình khi thực hiện post lên server thành một giá trị nào đó khác và lại muốn thử thay đổi thông tin orders của người khác. Lúc này bạn phải làm gì?
Lúc này, bạn PHẢI quản lý data không chỉ dựa vào orders#id mà còn phải dựa vào
orders#customer_id, phải check xem đối tượng data thao tác có đúng là của người chủ sở hữu không? (login_id); đặc biệt là với 2 trường hợp edit và xóa.

Một ví dụ để bạn dễ hình dung:

Một hệ thống có nhiều phiếu giảm giá. Phiếu giảm giá sẽ quy định mức giảm giá + thời hạn dùng, các thông tin khác…
Có thể có bạn sẽ làm như sau:

  1. Nhập mã giảm giá
    2. Thông tin từ mã giảm giá đó được lấy về và hiển thị trên màn hình
    3. Nhấn save thì mức tiền giảm giá hiển thị trên màn hình sẽ được post lên và lưu vào database

Nếu một người không chuyên IT thì hệ thống như vậy là không có vấn đề gì. Thế nhưng, sẽ không may nếu có một bạn IT nào đó muốn kiểm tra hệ thống của bạn. Nếu họ sửa số tiền hiện thị trên màn hình của bạn thêm vài số 0 rồi họ mới nhấn save thì sẽ thế nào?
Khi đó, hệ thống của bạn đã bonus cho họ một số tiền không nhỏ, thiệt hại này sẽ ra sao?
Thế nên khi làm, các bạn KHÔNG nên tin vào bất cứ cái gì của người dùng post lên. Chỉ nên tin vào cái gì đang có trong database của mình thôi.
Với case như trên, khi save chúng ta chỉ post lên mã code giảm giá trên server sẽ thực hiện việc validation cũng như get xem mã giảm giá đó bao nhiêu tiền và thực hiện giảm giá bằng đúng giá tiền được giảm trong database.
Đến đây các bạn hiểu tại sao lại phải validation các giá trị mà người dùng post lên rồi đúng không?

Cần đặc biệt lưu ý khi đó là các dự án liên quan đến tiền, thông tin cá nhân hay mail.

———————————————-

Cảm ơn mọi người đã đọc!

                                                        Quý Miêng – CO-WELL Asia

Xem thêm bài viết chủ đề công nghệ tại đây.
Đọc thêm nhiều thông tin thú vị về CO-WELL Asia tại đây.