thảo luận Best practice cho việc throw exception?

ý tầng business gặp lỗi kiểu validation, not found thì phải trả về api layer để nó trả lại status code phù hợp chứ bác, ý em là mấy cái lỗi như thế còn lỗi kiểu null, disconnect thì có 1 lớp middleware để catch là chắc chắn rồi
Cái thím nói là business rule rồi chứ ko gọi là exception. Nó sẽ giống như là "hiện UI 404 nếu nhập vào id không tồn tại". Lúc đó thì phải xử lý if/else thôi
 
Cái thím nói là business rule rồi chứ ko gọi là exception. Nó sẽ giống như là "hiện UI 404 nếu nhập vào id không tồn tại". Lúc đó thì phải xử lý if/else thôi
ý em là
Java:
class UserService {
    public User getUserInfo(int id) {
        // logic
        if (...) {
             throw UserNotFoundException("user not found");
        }

    }
}

Java:
class UserHttpController {
    private UserService userService;

    @GetMapping("/users/{id}")
    public Response<User> getUser(@RequestParam int id) {
 try {
    User user = userService.getUser(id);
    return Response(Http.Ok, ...);
 } catch (UserNotFound e) {
    return Response(Http.NotFound, ...);

 } catch (Exception e) {
    return Response(Http.Internal, ...);
   }
}

}

hay là các bác dùng kiểu gì khác kiểu này để tối ưu code hơn vậy
 
có 2 loại lỗi là error/lỗi và exception/ngoại lệ. Error là cái dễ xảy ra hơn exception. Exception thì phải chạy 1000 lần có 1 lần bị lỗi thì mới gọi là exception. Có câu "exception must be exceptional". Ngoại lệ phải là chuyện gì thặc khó có thể xảy ra được mới gọi là ngoại lệ. Error thì sao cũng được.
Validate password sai mà bảo là ngoại lệ thì bị khùng à
3916-pepedumb.png
khác mẹ gì bảo viết hàm kiểm tra 1 số có phải số nguyên tố ko có nên trả về ngoại lệ ko khi số đó là số nguyên tố. Trả về đúng/sai hoặc error code valid/invalid rồi if else check thôi
Dcnffay.png


if/else vs try/catch thì có trade off cả. If else thì luôn tốn 1 so sánh, branch prediction gì đó có thể coi là 5-10 cpu cycle đi. Còn try/catch thì nếu ko có ngoại lệ sẽ ít hơn branch prediction, cho là mất khoảng 2-4 cycle đi, nhưng nếu gặp ngoại lệ sẽ tốn 1000 cycle. Nếu tỉ lệ gặp "ngoại lệ" lên tới 50% thì code chạy tốn 500 cycle mỗi lần try/catch, chậm hơn if/else 100 lần, nên mới có câu nói throw ngoại lệ chậm lắm. Vì vậy throw ngoại lệ phải thực sự là ngoại lệ tỉ lệ 1/1000 xảy ra thì mới throw để try/catch lẹ hơn if/else, mà code dễ đọc hơn, còn tỉ lệ lỗi cao quá thì trả về error code rồi dùng if/else mà check.

Thực tế thì rất nhiều thằng framework nổi tiếng impl kiểu này, validation cũng dùng exception hết :shame:
 
ý em là
Java:
class UserService {
    public User getUserInfo(int id) {
        // logic
        if (...) {
             throw UserNotFoundException("user not found");
        }

    }
}

Java:
class UserHttpController {
    private UserService userService;

    @GetMapping("/users/{id}")
    public Response<User> getUser(@RequestParam int id) {
 try {
    User user = userService.getUser(id);
    return Response(Http.Ok, ...);
 } catch (UserNotFound e) {
    return Response(Http.NotFound, ...);

 } catch (Exception e) {
    return Response(Http.Internal, ...);
   }
}

}

hay là các bác dùng kiểu gì khác kiểu này để tối ưu code hơn vậy
Như tôi thì trả về null thôi, throw exception vẫn được nhưng như vậy phải try/catch ở tầng bên trên rườm rà.
 
Btw nói chung thì throw Exception vs. return Error Code/Result vẫn là đề tài tranh cãi hơn 20 năm nay rồi, giống như ORM vs. None ORM vậy. Tùy thuộc quan điểm của người impl thôi, nhiều framework top ten vẫn throw exception ầm ầm ở những chỗ "có vẻ không phải là exceptional" (Spring, Symfony...).

Mình thì trước giờ quen kiểu domain layer thì throw exception vì đơn giản là nếu return error thì cái layer ngay bên ngoài nó phải handle nhưng mà thực tế có những case bypass luôn, chỉ cần layer ngoài cùng handle nên throw thấy hợp lý.
Mặt khác exception nó mang thông tin nhiều hơn và dễ handle hơn, nếu nằm trong domain thì lại càng phù hợp.
 
Như tôi thì trả về null thôi, throw exception vẫn được nhưng như vậy phải try/catch ở tầng bên trên rườm rà.
ví dự 1 lỗi cơ bản vậy thì em nghĩ trả về null là cách nhanh nhất rồi, cơ mà nếu nhiều thứ hơn thì nên ntn ạ, kiểu như 400, hoặc 404 hoặc 429 đều có thể xảy ra ở cùng 1 business layer, nếu trả null thì làm sao phân biệt được lỗi ạ?

em thấy trong thư viện gốc của Java, nếu đọc file mà không thấy file đâu thì cũng throw exception, đọc legacy code của 1 cái dự án htrc em có làm được 1 2 task thì họ throw luôn.

thấy có bác trả về code hoặc enum nhưng không biết các bác khác ntn
 
tại sao thrown ex nó lại tốn tới 1000 cycle vậy thím, cái này hay nè, code thì đẹp hơn if/else mà performance thì tệ thế nhỉ ?

Có lẽ giờ CPU quá mạnh rồi, nên dev ko quan tâm vụ này lắm, trừ khi nó quá chậm.
đại loại là trong java thì exception được đẩy lên heap, thì allocation và garbage collecting cũng tốn kha khá resource rồi. Còn c# hình như là có optimize lại, đặt lên stack. Em đọc trên reddit chứ cũng k biết :whistle:
 
Vẫn là fan cứng của Error over Exception, mình có thể thêm details cho Error thoải mái như errorCode, messages,... Error nó explicit, nằm ở return type, còn Exceptions mấy ai mà note kỹ vào cái /** ... */

Devs khác reuse thì thoải mái hơn, tránh dc mấy cái PROD bugs ko đáng kể.
 
Vẫn là fan cứng của Error over Exception, mình có thể thêm details cho Error thoải mái như errorCode, messages,... Error nó explicit, nằm ở return type, còn Exceptions mấy ai mà note kỹ vào cái /** ... */

Devs khác reuse thì thoải mái hơn, tránh dc mấy cái PROD bugs ko đáng kể.

nếu Error extends Exception thì vẫn thỏa mãn mấy cái trên, dễ quản lý nữa
 
Cái thím nói là business rule rồi chứ ko gọi là exception. Nó sẽ giống như là "hiện UI 404 nếu nhập vào id không tồn tại". Lúc đó thì phải xử lý if/else thôi
case này thì em nghĩ tạo 1 cái error_handler, hoặc đại loại vậy catch cái not found rồi trả về 404 UI thì tiện hơn chứ nhỉ
khi nào cần trả 404 thì quăng 1 cái exception not found thôi
 
lại mấy thằng nâng cao quan điểm, k dùng exception thì if/else banh cái code à
Vậy thím xử lý exception sao mà ko if/else khi có nhiều loại exception 🤔
If/else nhiều là chuyện quá bình thường, chỉ cần tập trung và return sớm để tránh code branching là đc

via theNEXTvoz for iPhone
 
Vậy thím xử lý exception sao mà ko if/else khi có nhiều loại exception 🤔
If/else nhiều là chuyện quá bình thường, chỉ cần tập trung và return sớm để tránh code branching là đc

via theNEXTvoz for iPhone
Ở cty mình hay sử dụng multy catch để handle cho từng case cụ thể. Còn ở phía font end thì lúc mình nhận được Exception mình có thể switch case dựa vào mỗi type của nó để handle (ví dụ như là mỗi loại exception sẽ show 1 popup khác nhau)
 
Sửa lần cuối:
Ở cty mình hay sử dụng multy catch để handle cho từng case cụ thể. Còn ở phía font end thì lúc mình nhận được Exception mình có thể switch case dựa vào mỗi type của nó để handle (ví dụ như là mỗi loại exception sẽ show 1 popup khác nhau)
Thím cho hỏi bên FE thím dùng gì để switch thế? Http status code hay là custom code riêng
 
Ở cty mình hay sử dụng multy catch để handle cho từng case cụ thể. Còn ở phía font end thì lúc mình nhận được Exception mình có thể switch case dựa vào mỗi type của nó để handle (ví dụ như là mỗi loại exception sẽ show 1 popup khác nhau)
multi catch nó cũng như if else thui, thêm 1 exception type là phải thêm 1 cái catch, ông kia bảo ko xài if/else nên mình mới hỏi xem ổng có cách nào hay hơn ko :D
mà bên thím chắc chỉ có 1 client (FE) - 1 server (BE) thui nhỉ, chứ api mà quăng exception cho client, lỡ có breaking change (thêm excpetion type) ở server, trên browser nó hiện ra hết cái stacktrace lun quá
 
multi catch nó cũng như if else thui, thêm 1 exception type là phải thêm 1 cái catch, ông kia bảo ko xài if/else nên mình mới hỏi xem ổng có cách nào hay hơn ko :D
mà bên thím chắc chỉ có 1 client (FE) - 1 server (BE) thui nhỉ, chứ api mà quăng exception cho client, lỡ có breaking change (thêm excpetion type) ở server, trên browser nó hiện ra hết cái stacktrace lun quá
Thường thì breaking change kia mình phải tự aware mà thím. Lúc implement lúc nào cũng phải catch luôn Exception tổng, ngoài ra mình còn handle global exception. Nên vụ xót kia cũng hiếm khi xảy ra.
C#:
try {   
}
catch(CustomException ex){
}
catch(Exception ex){
}
Còn stacktrace thì bên mình chỉ log lại thôi có lẽ do FE của mình là app desktop không phải browser.
 
có 2 loại lỗi là error/lỗi và exception/ngoại lệ. Error là cái dễ xảy ra hơn exception. Exception thì phải chạy 1000 lần có 1 lần bị lỗi thì mới gọi là exception. Có câu "exception must be exceptional". Ngoại lệ phải là chuyện gì thặc khó có thể xảy ra được mới gọi là ngoại lệ. Error thì sao cũng được.
Validate password sai mà bảo là ngoại lệ thì bị khùng à
3916-pepedumb.png
khác mẹ gì bảo viết hàm kiểm tra 1 số có phải số nguyên tố ko có nên trả về ngoại lệ ko khi số đó là số nguyên tố. Trả về đúng/sai hoặc error code valid/invalid rồi if else check thôi
Dcnffay.png


if/else vs try/catch thì có trade off cả. If else thì luôn tốn 1 so sánh, branch prediction gì đó có thể coi là 5-10 cpu cycle đi. Còn try/catch thì nếu ko có ngoại lệ sẽ ít hơn branch prediction, cho là mất khoảng 2-4 cycle đi, nhưng nếu gặp ngoại lệ sẽ tốn 1000 cycle. Nếu tỉ lệ gặp "ngoại lệ" lên tới 50% thì code chạy tốn 500 cycle mỗi lần try/catch, chậm hơn if/else 100 lần, nên mới có câu nói throw ngoại lệ chậm lắm. Vì vậy throw ngoại lệ phải thực sự là ngoại lệ tỉ lệ 1/1000 xảy ra thì mới throw để try/catch lẹ hơn if/else, mà code dễ đọc hơn, còn tỉ lệ lỗi cao quá thì trả về error code rồi dùng if/else mà check.
đồng tình với thím này, login sai thì là lỗi thôi, k nên là exception.
Tuy nhiên có rất nhiều framework sử dụng exception tại những chỗ k giống exception lắm. Nên tranh luận vụ này gần như k có hồi kết
GFgZ8w7.png
 
Giờ không ai đi if-else để check từng lỗi rồi xem nó là loại exception gì đâu, trông code vừa xấu vừa trùng, vừa khó đọc. Mấy bạn trên tìm hiểu cách handle global exception/ business exception nhé

Ngoài lề một tí: nãy có đọc ông nào ở trên bảo dùng try-catch là chậm? thực tế là nó chỉ xấu code, khó đọc thôi, chứ không hề chậm đâu.
 

Thống kê chủ đề

Ngày tạo
Lập Trình Viên Trẻ,
Người trả lời cuối
nchhnchh,
Trả lời
85
Lượt xem
16.458
Quay lại
Lên đầu trang