thắc mắc Exception Handling trong ASP.NET Core

  • Người tạo chủ đề Người tạo chủ đề darkblue92
  • Ngày bắt đầu Ngày bắt đầu

darkblue92

Junior Member
Hi các bác, mấy nay e đi phỏng vấn khá nhiều, mà có một điểm này muốn tham khảo các bác.
Họ hỏi em cách handle exception trong asp.net core. Do các dự án cũ em làm không có handle các exception này bên trong app .net, mà handle qua Nginx (tức là khi có exception gây lỗi 500 Internal Server Error, thì Nginx sẽ return về 1 file 500.html tĩnh, đương nhiên exception vẫn sẽ ghi vào log trên server và tụi em manual check log này).
Tuy nhiên, 2-3 chỗ hỏi e cách quản lí exception bên trong app .net. Em cũng có nói là có thể viết middleware, và sử dụng UseExceptionHandler để handle các case này (kèm theo inject logger service để ghi log). Tuy nhiên đa phần họ đều "cười" và skip luôn topic này. Có 1 chỗ em hỏi họ lý do, họ nói là em không có kiến thức, họ bảo phải dùng global exception để control mọi thứ, kể cả các 4xx status code cũng phải throw ra global exception này. Em có nói quan điểm của em là không cần thiết với 4xx code, nếu cần implement thì 5xx code cho global exception là đủ. Xong họ cũng cười và skip.
Không biết quan điểm của các bác thế nào?
 
Theo mình là quan điểm dùng middleware để global handle exception là hợp lí và tất nhiên là handle tất cả status > 400 và log lại. Việc này rất cần thiết sau khi lên PROD có thể monitor và detect issue.
Khi issue đã lên đến PROD thì là issue khá là khoai rồi vì đa số issue nhỏ đã được fix ở quá trình development. Thế nên việc log lại status > 400 là cần thiết.
 
Hi các bác, mấy nay e đi phỏng vấn khá nhiều, mà có một điểm này muốn tham khảo các bác.
Họ hỏi em cách handle exception trong asp.net core. Do các dự án cũ em làm không có handle các exception này bên trong app .net, mà handle qua Nginx (tức là khi có exception gây lỗi 500 Internal Server Error, thì Nginx sẽ return về 1 file 500.html tĩnh, đương nhiên exception vẫn sẽ ghi vào log trên server và tụi em manual check log này).
Tuy nhiên, 2-3 chỗ hỏi e cách quản lí exception bên trong app .net. Em cũng có nói là có thể viết middleware, và sử dụng UseExceptionHandler để handle các case này (kèm theo inject logger service để ghi log). Tuy nhiên đa phần họ đều "cười" và skip luôn topic này. Có 1 chỗ em hỏi họ lý do, họ nói là em không có kiến thức, họ bảo phải dùng global exception để control mọi thứ, kể cả các 4xx status code cũng phải throw ra global exception này. Em có nói quan điểm của em là không cần thiết với 4xx code, nếu cần implement thì 5xx code cho global exception là đủ. Xong họ cũng cười và skip.
Không biết quan điểm của các bác thế nào?
Ý tưởng của bác em thấy ok mà nhỉ, chỉ có quan điểm của bác thì 4xx bác không muốn ghi log ra và cho đi qua cái global exception handler này thôi. Như vậy mà người phỏng vấn phán bác không có kiến thức thì hơi ngáo.

Mình cũng có ý tưởng xử lý exception tương tự, exception mình phân ra 3 loại:
  • Có thể handle
  • Không handle được nhưng mình có thể biết trước được khi nào thì nó xẩy ra (thường là 4xx)
  • Không handle được và không biết nó xẩy ra lúc nào (Unexpected Exceptions - 5xx)

Với loại 2 và 3 thì mình cho đi qua global exception interceptor (Thường nằm ở middleware), Ở interceptor này mình sẽ trả về response với status code tương ứng + request_id (request_id này sẽ được gen ra ở nginx khi tiếp nhận request) + message error tương ứng, .... Quan trọng hơn mình sẽ ghi log những exceptions này (cả 4xx, lẫn 5xx), với 5xx mình sẽ ghi rõ ra traceback của nó. Khi frontend tiếp nhận response với status là 4xx, 5xx thì sẽ hiển thị popup thông báo lỗi (hoặc là trang html như chỗ bác phỏng vấn) + request_id, nếu gặp user tốt họ có thể copy lại request_id hoặc là capture màn hình, mình sẽ dựa vào request_id này để trace log được nhanh hơn. Với lỗi 5xx, ghi xẩy ra sẽ được gửi notification về 1 channel nào đó tùy theo công ty đang dùng channel chat nào để làm việc (slack, discord, ...)

Hóng ý kiến + kinh nghiệm từ các cao nhân.
 
Sửa lần cuối:
Hi các bác, mấy nay e đi phỏng vấn khá nhiều, mà có một điểm này muốn tham khảo các bác.
Họ hỏi em cách handle exception trong asp.net core. Do các dự án cũ em làm không có handle các exception này bên trong app .net, mà handle qua Nginx (tức là khi có exception gây lỗi 500 Internal Server Error, thì Nginx sẽ return về 1 file 500.html tĩnh, đương nhiên exception vẫn sẽ ghi vào log trên server và tụi em manual check log này).
Tuy nhiên, 2-3 chỗ hỏi e cách quản lí exception bên trong app .net. Em cũng có nói là có thể viết middleware, và sử dụng UseExceptionHandler để handle các case này (kèm theo inject logger service để ghi log). Tuy nhiên đa phần họ đều "cười" và skip luôn topic này. Có 1 chỗ em hỏi họ lý do, họ nói là em không có kiến thức, họ bảo phải dùng global exception để control mọi thứ, kể cả các 4xx status code cũng phải throw ra global exception này. Em có nói quan điểm của em là không cần thiết với 4xx code, nếu cần implement thì 5xx code cho global exception là đủ. Xong họ cũng cười và skip.
Không biết quan điểm của các bác thế nào?
Dùng middleware thì chính là handle global exception chứ còn gì nữa? quan điểm cá nhân thì nên có global exception để giảm bớt try catch ko cần thiết và catch các lỗi ko đc handle. Trong global sẽ handle các http status lỗi (4xx, 5xx), bên trong logic thì có thể throw ra cái exception tương ứng.
 
Ý tưởng của bác em thấy ok mà nhỉ, chỉ có quan điểm của bác thì 4xx bác không muốn ghi log ra và cho đi qua cái global exception handler này thôi. Như vậy mà người phỏng vấn phán bác không có kiến thức thì hơi ngáo.

Mình cũng có ý tưởng xử lý exception tương tự, exception mình phân ra 3 loại:
  • Có thể handle
  • Không handle được nhưng mình có thể biết trước được khi nào thì nó xẩy ra (thường là 4xx)
  • Không handle được và không biết nó xẩy ra lúc nào (Unexpected Exceptions - 5xx)

Với loại 2 và 3 thì mình cho đi qua global exception interceptor (Thường nằm ở middleware), Ở interceptor này mình sẽ trả về response với status code tương ứng + request_id (request_id này sẽ được gen ra ở nginx khi tiếp nhận request) + message error tương ứng. Quan trọng hơn mình sẽ ghi log những exceptions này (cả 4xx, lẫn 5xx), với 5xx mình sẽ ghi rõ ra traceback của nó. Khi frontend tiếp nhận response với status là 4xx, 5xx thì sẽ hiển thị popup thông báo lỗi (hoặc là trang html như chỗ bác phỏng vấn) + request_id, nếu gặp user tốt họ có thể copy lại request_id hoặc là capture màn hình, mình sẽ dựa vào request_id này để trace log được nhanh hơn. Với lỗi 5xx, ghi xẩy ra sẽ được gửi notification về 1 channel nào đó tùy theo công ty đang dùng channel chat nào để làm việc (slack, discord, ...)

Hóng ý kiến + kinh nghiệm từ các cao nhân.

Dùng middleware thì chính là handle global exception chứ còn gì nữa? quan điểm cá nhân thì nên có global exception để giảm bớt try catch ko cần thiết và catch các lỗi ko đc handle. Trong global sẽ handle các http status lỗi (4xx, 5xx), bên trong logic thì có thể throw ra cái exception tương ứng.
hmm 2 bác cho e hỏi nếu có cái global exception như thế thì mình có thể throw ở bất kì đâu (service layer, data access layer) nhỉ? chứ nếu ở tầng controller thì return giá trị (Ok(...), BadRequest(...), UnAuthorize(...) ,...) cho rồi chứ đâu cần throw ex ngay đây đúng không?
 
hmm 2 bác cho e hỏi nếu có cái global exception như thế thì mình có thể throw ở bất kì đâu (service layer, data access layer) nhỉ? chứ nếu ở tầng controller thì return giá trị (Ok(...), BadRequest(...), UnAuthorize(...) ,...) cho rồi chứ đâu cần throw ex ngay đây đúng không?
mấy cái này là lỗi mà bác có thể biết trước nó xẩy ra ở đâu thì bác return về controller như vậy. Còn trường hợp giả sử ở data access layer bác query xuống db mà db đang bị down thì hoặc là bác try catch ở data access layler rồi gửi exception về controller, nhưng như vậy thì bất kỳ functions nào ở data access layer bác cũng phải try cache hết, nhìn code rất gớm. Cái global exception handler như bác trên có nói là để tránh try catch không cần thiết đó.
 
Hi các bác, mấy nay e đi phỏng vấn khá nhiều, mà có một điểm này muốn tham khảo các bác.
Họ hỏi em cách handle exception trong asp.net core. Do các dự án cũ em làm không có handle các exception này bên trong app .net, mà handle qua Nginx (tức là khi có exception gây lỗi 500 Internal Server Error, thì Nginx sẽ return về 1 file 500.html tĩnh, đương nhiên exception vẫn sẽ ghi vào log trên server và tụi em manual check log này).
Tuy nhiên, 2-3 chỗ hỏi e cách quản lí exception bên trong app .net. Em cũng có nói là có thể viết middleware, và sử dụng UseExceptionHandler để handle các case này (kèm theo inject logger service để ghi log). Tuy nhiên đa phần họ đều "cười" và skip luôn topic này. Có 1 chỗ em hỏi họ lý do, họ nói là em không có kiến thức, họ bảo phải dùng global exception để control mọi thứ, kể cả các 4xx status code cũng phải throw ra global exception này. Em có nói quan điểm của em là không cần thiết với 4xx code, nếu cần implement thì 5xx code cho global exception là đủ. Xong họ cũng cười và skip.
Không biết quan điểm của các bác thế nào?
Cái xử lý exception chỉ cần với các dự án dài hơi đông người thôi, mới cần log nhiều, chi tiết từng loại lỗi, còn dự án ngắn hạn đánh nhanh rút gọn cứ throw mịa đi là xong, hơi đâu mà bắt chi tiết từng cái, thực tế nó là thế mấy thằng "cười" đấy chắc gì đã ngon hơn anh em bên ngoài

Tôi làm dotnet từ cái thời còn cái MVP nên đừng bảo tôi mới vào nghề nhé...
 
Cũng quan tâm và hóng cao nhân. Mình đọc thấy khó hiểu y chang thớt vì mình cũng dùng UseExceptionHandler middleware và mình cũng đồng ý với 1 bạn phía trên nói, đấy chính là global handle exception rồi còn gì nữa. Về 4xx code, phải mình mình sẽ hỏi ngược lại người phỏng vấn, throw ra global exception như thế thì có ích lợi gì? Cá nhân mình handle 4xx tách biệt với 5xx, dùng UseStatusCodePages middleware, và quan điểm mình cũng giống thớt là 4xx client error nói chung non-critical, làm tốt hơn được thì tốt ko thì thôi. Thớt sao ko hỏi sâu hơn? Phỏng vấn được nhận thì tốt mà ko thì thôi, nhưng nếu có thắc mắc mình nghĩ nên hỏi tới cùng chứ về mà còn lăn tăn thì rất là khó chịu.
 
Cũng quan tâm và hóng cao nhân. Mình đọc thấy khó hiểu y chang thớt vì mình cũng dùng UseExceptionHandler middleware và mình cũng đồng ý với 1 bạn phía trên nói, đấy chính là global handle exception rồi còn gì nữa. Về 4xx code, phải mình mình sẽ hỏi ngược lại người phỏng vấn, throw ra global exception như thế thì có ích lợi gì? Cá nhân mình handle 4xx tách biệt với 5xx, dùng UseStatusCodePages middleware, và quan điểm mình cũng giống thớt là 4xx client error nói chung non-critical, làm tốt hơn được thì tốt ko thì thôi. Thớt sao ko hỏi sâu hơn? Phỏng vấn được nhận thì tốt mà ko thì thôi, nhưng nếu có thắc mắc mình nghĩ nên hỏi tới cùng chứ về mà còn lăn tăn thì rất là khó chịu.
tại em cũng rén ấy, thất nghiệp cả tháng rồi nên trong lúc pv e cũng k dám tranh luận nhiều. thường người pv mà skip qua tức là họ ko thấy e đủ yêu cầu với dự án của họ rồi, nên thôi im luôn và đương nhiên là tạch :D
 
Cái xử lý exception chỉ cần với các dự án dài hơi đông người thôi, mới cần log nhiều, chi tiết từng loại lỗi, còn dự án ngắn hạn đánh nhanh rút gọn cứ throw mịa đi là xong, hơi đâu mà bắt chi tiết từng cái, thực tế nó là thế mấy thằng "cười" đấy chắc gì đã ngon hơn anh em bên ngoài

Tôi làm dotnet từ cái thời còn cái MVP nên đừng bảo tôi mới vào nghề nhé...
e cảm ơn ý kiến của bác, chắc do em xui vào pv gặp mấy người pv khó tánh, thời giờ thị trường khó khăn nên họ tuyển gắt gao. cũng có một số chỗ e gặp người pv rất nice, e trả lời sai ở đâu họ liền có feedback ngay lập tức để e rút kinh nghiệm.
 
namespace API.Errors;
public class ApiException(int stattusCode, string message, string? details)
{
public int StattusCode { get; set; } =stattusCode;
public string Message { get; set; } = message;
public string? Details { get; set; } = details;
}
Mình tạo cái middleware như này.
namespace API.Middleware;
public class ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger,
IHostEnvironment env)
{
public async Task InvokeAsync(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{

logger.LogError( ex, ex.Message );
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var response = env.IsDevelopment()
? new ApiException(context.Response.StatusCode, ex.Message, ex.StackTrace)
: new ApiException(context.Response.StatusCode, ex.Message, "Internal server error");
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var json = JsonSerializer.Serialize(response, options);
await context.Response.WriteAsync(json);
}
}
}
 
tại em cũng rén ấy, thất nghiệp cả tháng rồi nên trong lúc pv e cũng k dám tranh luận nhiều. thường người pv mà skip qua tức là họ ko thấy e đủ yêu cầu với dự án của họ rồi, nên thôi im luôn và đương nhiên là tạch :D
Vậy lần sau cứ mạnh dạn hỏi sâu, kể cả ko được thì cũng là cơ hội nâng cao trình độ.

Đây ko phải chuyện tranh luận hay ko mà là hiểu rõ nguyên nhân tại sao lại có lựa chọn đấy cũng như trade-off. Chứ còn, cụ thể vấn đề của bạn, bình thường mà nói, luôn có nhu cầu biết error phát sinh từ logic server hay request tồi, cho nên mới sinh ra code 4xx hay 5xx, bởi vậy mình luôn tách ra để handle. Ngoài ra là developer thì về cơ bản quan tâm nhiều hơn đến lỗi phát sinh từ logic, chứ do bad request thì pass sang cho bộ phận khác handle, như bộ phận bảo mật, chẳng hạn thế.

Mà chỗ nào hỏi error handling thì tận dụng cơ hội hỏi sâu vào. Handle errors đầy đủ, chuẩn, nói thật cực như chóa, đã vậy stakeholders non technical có khi chẳng đánh giá cao, nên nhìn chung đây là phần nát nhất, chuyện cứ throw mịa đi là xong như bạn trên nói thực tế nhiều như lợn con. Application ngon hay ko nhìn cách handle error thế nào là biết, cho nên lần sau bạn hãy hỏi thật nhiều vào. Người ta nói quan điểm thì đừng nêu quan điểm của mình vội khi chưa biết lý do tại sao họ làm thế, phải hỏi trước, hiểu rõ rồi thì mới tranh luận.
 
Mình tạo cái middleware như này.
Cảm ơn sample code của bác, e cũng trình bày cách implement tương tự nhưng có vẻ interviewer họ k chịu, maybe là khác cái cách họ đang làm.
Vậy lần sau cứ mạnh dạn hỏi sâu, kể cả ko được thì cũng là cơ hội nâng cao trình độ.

Đây ko phải chuyện tranh luận hay ko mà là hiểu rõ nguyên nhân tại sao lại có lựa chọn đấy cũng như trade-off. Chứ còn, cụ thể vấn đề của bạn, bình thường mà nói, luôn có nhu cầu biết error phát sinh từ logic server hay request tồi, cho nên mới sinh ra code 4xx hay 5xx, bởi vậy mình luôn tách ra để handle. Ngoài ra là developer thì về cơ bản quan tâm nhiều hơn đến lỗi phát sinh từ logic, chứ do bad request thì pass sang cho bộ phận khác handle, như bộ phận bảo mật, chẳng hạn thế.

Mà chỗ nào hỏi error handling thì tận dụng cơ hội hỏi sâu vào. Handle errors đầy đủ, chuẩn, nói thật cực như chóa, đã vậy stakeholders non technical có khi chẳng đánh giá cao, nên nhìn chung đây là phần nát nhất, chuyện cứ throw mịa đi là xong như bạn trên nói thực tế nhiều như lợn con. Application ngon hay ko nhìn cách handle error thế nào là biết, cho nên lần sau bạn hãy hỏi thật nhiều vào. Người ta nói quan điểm thì đừng nêu quan điểm của mình vội khi chưa biết lý do tại sao họ làm thế, phải hỏi trước, hiểu rõ rồi thì mới tranh luận.
E cảm ơn ý kiến của bác. Thực ra e đi pv đâu đó hơn chục cty, rất hiếm khi người ta chia sẻ kinh nghiệm trong buổi pv, thậm chí lúc tạch e xin feedback thì cũng chung chung. Tựu chung lại e thấy trong buổi pv cũng ko có học hỏi thêm gì được từ interviewer, mặt khác còn khá nhiều topic khác cần cover nữa, nên e nghĩ khi mình mong muốn đào sâu/hỏi kĩ hơn thì họ lại không vui và tốn thời gian họ, thì cơ hội tạch mình lại x2 x3 nên e cũng ko dám :(
 
Cảm ơn sample code của bác, e cũng trình bày cách implement tương tự nhưng có vẻ interviewer họ k chịu, maybe là khác cái cách họ đang làm.

E cảm ơn ý kiến của bác. Thực ra e đi pv đâu đó hơn chục cty, rất hiếm khi người ta chia sẻ kinh nghiệm trong buổi pv, thậm chí lúc tạch e xin feedback thì cũng chung chung. Tựu chung lại e thấy trong buổi pv cũng ko có học hỏi thêm gì được từ interviewer, mặt khác còn khá nhiều topic khác cần cover nữa, nên e nghĩ khi mình mong muốn đào sâu/hỏi kĩ hơn thì họ lại không vui và tốn thời gian họ, thì cơ hội tạch mình lại x2 x3 nên e cũng ko dám :(
Thực tế nhiều thằng leader, tech lead có thể bị "ép" phải đi interview cho cty vì nó ko đc thêm xu nào, và cũng chẳng thích interview nên mặt nó khó chịu là bth, chưa kể 1 số thằng tính cách vào loại ẩm ương (mấy thằng IT EQ cực kém). Nên cái chuyện mà đào sâu với lại hỏi kĩ là vớ vẩn, xong việc là én, vậy thôi, căn bản ai cũng làm vì tiền, hết.
 
Thực tế nhiều thằng leader, tech lead có thể bị "ép" phải đi interview cho cty vì nó ko đc thêm xu nào, và cũng chẳng thích interview nên mặt nó khó chịu là bth, chưa kể 1 số thằng tính cách vào loại ẩm ương (mấy thằng IT EQ cực kém). Nên cái chuyện mà đào sâu với lại hỏi kĩ là vớ vẩn, xong việc là én, vậy thôi, căn bản ai cũng làm vì tiền, hết.
E thấy đúng, nhiều khi đang chạy task mà bắt đi phỏng vấn thì họ cũng dễ cọc. Cảm ơn ý kiến của bác.
 
Èo, đồng ý là vì tiền nhưng vẫn có những người thích chém về công nghệ mà. Nghĩ thoáng ra, coi đấy nó như câu cá, có thể ko câu được hoặc không nhưng mồi thì vẫn luôn phải chuẩn bị. Cần hỏi vẫn nên là hỏi. Có phải công ty nào cũng giống nhau hết đâu. Trước mình PV với 1 công ty nhóm FAANG, có nhiều round nhưng có nguyên 1 round với tech lead mình có thể hỏi bất cứ câu hỏi nào về cái họ đang làm, rất là dễ chịu.
 
bạn có thể cho mình tham khảo list câu hỏi phỏng vấn không, mình cũng định nhảy nên muốn test xem kiến thức bị thiếu chỗ nào
 

Thống kê chủ đề

Ngày tạo
darkblue92,
Người trả lời cuối
longvungoc,
Trả lời
19
Lượt xem
2.036
Quay lại
Lên đầu trang