If you can use Serilog then integrating DB, file email sinks is quite simple "Serilog": { "Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Email", "Serilog.Sinks.MSSqlServer", "Serilog.Sinks.Console" ] Its just configuration and minimal registration of Serilog in Program.cs
I wonder regarding the validationException you had there, I assume fluentValidation Isnt it having some performance hit throwing a validation exception rather then just getting the validation result object and look at the IsValid property? Its true that its more clean without the if statement, but is it more performant to enter a try catch statement for every place you have validation?
Hi Julio, thank you for this video especially for writing tuple i just found out in that way. Anyway, how to get the request body? It can help us to identify or reproduce the error.
@@juliocasal iv tried this: string requestBody = await new StreamReader(httpContext.Request.Body).ReadToEndAsync(); httpContext.Request.Body.Position = 0; but always return null or empty.
@@juliocasal finally i found the solotution to get request body using: using (var reader = new StreamReader(httpContext.Request.Body)) { // Reset the stream position to the beginning after enabling buffering httpContext.Request.Body.Seek(0, SeekOrigin.Begin); // Read the request body as a string var requestBody = await reader.ReadToEndAsync(); // Process the request body as needed Console.WriteLine(requestBody); } and set context.Request.EnableBuffering(); in program.cs or middleware.
What's the best way to handle exceptions in microservices architecture? Can I create a shared project and reference the custom exception classes in each microservice? Is there a better approach ? Thanks
Need to think a bit about this. Should be easy enough to have a global handler on each microservice, since each one might have their own custom exceptions.
Thanks for sharing. What happens if I have like 20 services?Does that means I will have to chain the AddProblemDetails() and the GlobalExpection extension on every service injection? How can I handle that?
I mean if I have multiple repos services, will I e chaining the AddProblemDetails() and the GlobalExpection for each one of them or is there a better way to handle that? @@juliocasal
@@juliocasalI believe because you chained the addproblemdetails to a addsignleton it looks like thr exception handler is attached to that Singleton. I believe it's attached to the service collection instead but the chaining looks like it's scoping the exception to the Singleton.
I don't like the idea of mapping all errors of one type (unless you have one custom type specially for this) into an error message, especially when it's a stdlib exception. It feels like info could be leaked accidently and it should be done within the api endpoint handler explicitly. This also means the valid responses (I am also meaning the errors) are contained in one place and accessible to developers rather than hidden and magic. Thanks for the video, was good.
That's fair. I used standard exceptions just to keep things simple, but you can use all sorts of custom exceptions there. You have full control of how each exception is mapped, so there should be no accidental leaks. Also, using a global exception handler is a very standard practice, so I don't think it's hidden and magic. Glad you liked the video!
good tutorial ,Is there any way to gracefully add exceptional status codes in this custom exceptional handler.As of now we are adding them manually ,this may get cumbersome.Appreciate reading my comment!
It's cool that the .NET team is formally supporting this commonly used pattern, but I don't like that it always catches _all_ exceptions, and the only way to handle specific types of exception is via reflection. If I could specify an exception type as a generic type argument for the "UseExceptionHandler" method, something like "UseExceptionHandler()", that would be ideal. Maybe in .NET 9.
As usual very neat and useful.
Glad you think so!
Very nice! Thanks Julio! This kind of videos are awesome!
Glad you liked it!
Great and detailed information. Thanks
Glad it was helpful!
Hi @juli , could you please make a video to how we can save these logs into database or in third party logging system like loggly, or scaler ?
I cover that here: dotnetmicroservices.com
If you can use Serilog then integrating DB, file email sinks is quite simple
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Email", "Serilog.Sinks.MSSqlServer", "Serilog.Sinks.Console" ]
Its just configuration and minimal registration of Serilog in Program.cs
I wonder regarding the validationException you had there,
I assume fluentValidation
Isnt it having some performance hit throwing a validation exception rather then just getting the validation result object and look at the IsValid property?
Its true that its more clean without the if statement, but is it more performant to enter a try catch statement for every place you have validation?
Which validation exception? Not using FluentValidation here.
@julio prior to dotnet 8, would we just add a middleware try/catch and handle it that way?
Prior to .NET 8, you can do this: ua-cam.com/video/nycII-Cec9I/v-deo.html
Hi Julio, thank you for this video especially for writing tuple i just found out in that way.
Anyway, how to get the request body? It can help us to identify or reproduce the error.
Glad to help. Have not tried getting the request body.
@@juliocasal iv tried this:
string requestBody = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();
httpContext.Request.Body.Position = 0;
but always return null or empty.
@@juliocasal
finally i found the solotution to get request body using:
using (var reader = new StreamReader(httpContext.Request.Body))
{
// Reset the stream position to the beginning after enabling buffering
httpContext.Request.Body.Seek(0, SeekOrigin.Begin);
// Read the request body as a string
var requestBody = await reader.ReadToEndAsync();
// Process the request body as needed
Console.WriteLine(requestBody);
}
and set context.Request.EnableBuffering(); in program.cs or middleware.
Really useful stuff.Thanks!
btw is that code completion coming from copilot or some VS extension?
Thanks! That's Copilot.
What's the best way to handle exceptions in microservices architecture?
Can I create a shared project and reference the custom exception classes in each microservice?
Is there a better approach ?
Thanks
Need to think a bit about this. Should be easy enough to have a global handler on each microservice, since each one might have their own custom exceptions.
A Nuget package could be also ok for this purpose to handle all logs to a service like elasticsearch .
Thanks for sharing. What happens if I have like 20 services?Does that means I will have to chain the AddProblemDetails() and the GlobalExpection extension on every service injection? How can I handle that?
Could you clarify what you mean by "services"? You mean application services in your single app? Or you mean multiple microservices?
I mean if I have multiple repos services, will I e chaining the AddProblemDetails() and the GlobalExpection for each one of them or is there a better way to handle that? @@juliocasal
@@juliocasalI believe because you chained the addproblemdetails to a addsignleton it looks like thr exception handler is attached to that Singleton.
I believe it's attached to the service collection instead but the chaining looks like it's scoping the exception to the Singleton.
Thanks :)
Welcome!
I don't like the idea of mapping all errors of one type (unless you have one custom type specially for this) into an error message, especially when it's a stdlib exception. It feels like info could be leaked accidently and it should be done within the api endpoint handler explicitly. This also means the valid responses (I am also meaning the errors) are contained in one place and accessible to developers rather than hidden and magic.
Thanks for the video, was good.
That's fair. I used standard exceptions just to keep things simple, but you can use all sorts of custom exceptions there. You have full control of how each exception is mapped, so there should be no accidental leaks. Also, using a global exception handler is a very standard practice, so I don't think it's hidden and magic.
Glad you liked the video!
good tutorial ,Is there any way to gracefully add exceptional status codes in this custom exceptional handler.As of now we are adding them manually ,this may get cumbersome.Appreciate reading my comment!
?
@@juliocasalI mean the way we are mapping exceptions to status codes in switch statement
It's cool that the .NET team is formally supporting this commonly used pattern, but I don't like that it always catches _all_ exceptions, and the only way to handle specific types of exception is via reflection.
If I could specify an exception type as a generic type argument for the "UseExceptionHandler" method, something like "UseExceptionHandler()", that would be ideal. Maybe in .NET 9.
Great feedback! If you get a chance, you can always provide direct feedback here: github.com/dotnet/aspnetcore