Hey there! In this channel I'm creating industry-level tutorials about coding, design patterns, architecture, and the latest and greatest libraries, tricks, and tips you should definitely know about.
Great Videos, Please can you do one on Composition and Or with Strategy Pattern, I have been struggling with these for months.
@floriandraxler3868Күн бұрын
is that video speed up a little or do you have some sort of voice adjustment going on?
@yufgyug3735Күн бұрын
Ive been using this approach for a long time now. What i like about it, is that it forces you to deal with some code smells 1. exceptions are for exceptional situations - for example, a method parameter should under no circumstance be a null, but somehow is - the program cannot continue handling the request 2. explicitly deal with specific error situations - how do we handle situation X? how do we handle situation Y?
@Tony-dp1rl2 күн бұрын
Using exceptions for logic branches that you KNOW how to handle without exceptions, such as by returning a suitable response, is not a good idea. It creates a different user experience in most cases, and it creates far more overhead in terms of error logging, monitoring, unit testing, etc. Nothing worse than a unit test, or functional/integration test, that has to say "did this throw an exception?" .. "yes, test passed" ... just stupid :)
@amantinband2 күн бұрын
I generally agree and have videos on the channel relaying this exact point. The truth is in the middle. Both approaches have great benefits and drawbacks. I’m demonstrating what I would personally use for a small-medium, mostly CRUD app when looking to get things up and running as fast as possible.
@dougbas39803 күн бұрын
Very powerful tool. Yoou have convinced me this is a tool I need. THANK YOU.
@patfre3 күн бұрын
Exception should only ever be used IF AND ONLY IF ITS THE ONLY OPTION. Exceptions are incredibly memory and processing intensive and should be reduced as much as possible so even suggesting to use it just because it’s simpler is one heck of a quick way to make people fail an interview
@amantinband2 күн бұрын
Sounds like you’ll enjoy this video: Exceptions are evil. This is what I do instead. kzread.info/dash/bejne/ZJydrdt_mZTTl6w.html
@relax4o3 күн бұрын
Hi Amichai, I think you missed another solution which is also used by Vaughn Vernon. Have you considered creating a separate value object that holds the reference ids? For example "record HostMenu(HostId hostId, MenuId menuId);" which then can be easily used in OwnsMany() and you can again define each with HasConversion(). I think this approach is easier to understand and depending on UL, it can bring better clarity. For example, in IDDD book VV is using a value object CommittedBacklogItem within the Sprint aggregate and that value object is used in a HashSet inside the Sprint object. I really like that approach because it also brings a good understanding of what that actually mean for the sprint. It's not just a list of backlog items but they are actually backlog items committed for the sprint. Same goes for ScheduledBacklogItem within the Release aggregate. Also, in version 8 the EF Core team introduced a ComplexProperty which is really good for such cases, though, it's still very limited and they cannot yet properly be used for collections or keys but once they improve them it will be really cool feature to use.
@IoannisHorgos-bv1in3 күн бұрын
Great video! Thank you for your effort! What software do you use for creating these boxes and arrows as you drag your mouse?
@amantinband2 күн бұрын
Presentify
@ErikVasilyan1833 күн бұрын
Talking about DDD, what you think about to never have conditionals in application services? I see you do "productRepository.Exists()" and checking if product exists, if it exists you create the review if not you throw. To not have logic like that in app service you could do that your product domain model creates the review, like "product.CreateReview()". So in app service you get the actual product doing "productRepository.getProduct(ProductId)" and you get the product or else throw, then you create the review using that product.
@amantinband2 күн бұрын
What’s the motivation for not having conditionals in application services?
@saiuan45623 күн бұрын
Why not just return either the record, or 200 OK with empty list/no record, if it was not found? Is that not okay?
@amantinband2 күн бұрын
Both approaches are good and valid. Personally, if I get to choose, I return 404 for *parent* resource not found, and 200 ok and empty list for collection not found/empty
@SodalisUK5 күн бұрын
Does the same principle apply to other languages (python, php for example) that have exceptions and can you have an equivalent to ErrorOr in those languages?
@iantabron5 күн бұрын
I generally disagree with throwing exceptions in non-exceptional circumstances. However, in this example I more strongly disagree with throwing an exception in a service layer that contains an HTTP response code. You are assuming you will always use your service layer with a web-based API, and tying it to this usage. A service layer should be just that - services. An API layer, such as WebAPI in this case, should have the responsibility of returning the appropriate HTTP response code.
@amantinband5 күн бұрын
Please note that we’re talking about simple, small to medium applications that are mostly CRUD. I share your opinion for larger, more complex applications. For the smaller apps, personally, I’d choose the higher coupling, higher cohesion approach and refactor if needed
@georgebelletty78615 күн бұрын
I do like ErrorOr I use it in all our projects
@WasifKizilbash5 күн бұрын
The best, concise, to-the-point, relevant and CLEAR communication!! above all, I really like the way you kept on showing the Diagram and linked it with the Code, that is where we are! I've never seen any .NET video instructors making such a clear and crisp connection to the Infographic vs Code!! great stuff! will definitely cover your entire course!! This is coming from a full stack .NET developer who has been dirtying hands for the last 15 years!! bravo! more power to you mate! love from Australia!
@maxweinbrown11805 күн бұрын
"Repositories go into either the application or domain layers" I believe their implementation goes into the infrastructure layer, but their definition (if you're working with interfaces/headers/protocols) belongs to the domain layer. This keeps the domain from being dependent on the infra layer, while still making use of it, often through dependency injection
@petherpettersson61526 күн бұрын
What I can't really buy on the cons of Exceptions is the cost of them, sure, it has some resource cost, but who designs a product to do the bad incorrect stuff all the time? There's supposed to be validation on input on the frontend, the one on backend is just a safeguard, so will have no Exceptions there if the frontend has done it's job, so then the only exceptions coming are the ones where something goes bad during processing?
@amantinband6 күн бұрын
When using exceptions for flow control, by definition you’re using exceptions for flows that are not exceptional. Depending on the scale and requirements of the app, this can be significant
@LarryGroot6 күн бұрын
Thank you very much. Maybe Next Video how you would log and which framework you would use.
@amantinband6 күн бұрын
It’s coming
@kennethcanet16336 күн бұрын
discount code invalid.
@robertmills81016 күн бұрын
Why are you separating command and query outside of IAuthenticationService? No code outside of the implementation cares. You're introducing something and a LOT of code that doesn't matter. The implementation of authentication's repository (maybe IAuthenticationRepository) might care because there is a read side and a write/transaction side, but not at the front end or what should be a very thin, single line, of code in the controller. Oh, and what happens if login requires a counter update to restrict failures every n minutes? Also, even query commands will/might update the log database, but I guess that doesn't count. Sorry for the rant.
@ameyashinde4236 күн бұрын
Learnt something new. Thanks so much
@pilotboba7 күн бұрын
One thing I disagree with is ever returning a 404 on a List (collection) endpoint. I'm not sure why your List asked for a product Id. But a list should return an empty collection if no resources match the predicate.
@amantinband7 күн бұрын
If it's up to me, I choose 404 for parent resource not found, but both are fine and valid approaches
@pilotboba7 күн бұрын
@@amantinband Oh so you are listing some child resources of a product. I guess I could see returning a 404 in the case of the missing product.
@jimread23547 күн бұрын
That's funny, I completely and fundamentally disagree. IMO, if you have a simple application, you can use return codes, but complex applications with lots of shared code and deep stacks of function calls benefit enormously from Exceptions. Exceptions simplify error handling and code readability MASSIVELY over returning error codes. Exceptions were a response to return codes' lack of scalability because return codes require that EVERY time a function is called, whatever calls it has to have logic to handle the error condition right there. Exceptions allow you to simply pass the error up the chain until something that cares or knows what to do will actually handle it. Further, exception handling is done outside the general flow of logic so someone reading the code can actually understand what is 'supposed' to be happening and there's no chance that anything UP the stack is going to continue executing in a faulty state. On top of that, IMO, it's a TERRIBLE idea to have multiple outputs from a given function. It's bad enough to have the possibility of null or an object, but to then throw in the possibility of a third type to check and unpack the result of every function call? How is that scalable? It's a rat's nest of error handling! That's the beauty of an 'out' parameter is you can have the function return a specific type of result and then use the object if it's valid or else handle the case of it not being valid. The other great power of an Exception is that you can add context as the stack unwinds at the levels where it makes sense. Return codes can only change the context and you might lose vital information about what happened in the error situation. You're basically left with the choice of a user being told that there was a divide by zero error OR that the review didn't get added with no information about WHY. For instance, in a complex application a UI action will likely start a cascade of function calls splitting off into different directions to handle the different subtasks associated with with whatever the user just asked for. An exception deep in the bowels of that can say there was a divide by zero error, but then that can propagate to a failure to generate a star rating value which can then be caught closer to the UI level and told that the review couldn't be added. When you're building the message for the user and the message for the log, you'll have different info you can use to generate useful information in both contexts right at your fingertips without generating multiple log entries that you have to then piece together. IMO, you should throw Exceptions if the code you're in can't handle the current logical situation. For instance, adding a review to a product that doesn't exist. But if the code you're in CAN handle the situation, like perhaps you're adding an item to a list of items that share some property, but nothing has been added with that particular property yet, you should create the list for those items--no need for an exception or return code. Not using exceptions and relying on return codes is going backwards. And returning multiple data types from a function has always been a really bad idea from a readability and usability standpoint. The only real use case for return codes is in headless programs or highly performant libraries; but you better be sure the tradeoff in readability and debuggability is worth it.
@amantinband7 күн бұрын
Thanks for taking the time to share your thought and experience. My opinion around this topic is shaped from suffering bad implementations of exceptions for flow control in numerous large complex projects within Microsoft. I elaborate my opinion in more detail in this video: kzread.info/dash/bejne/ZJydrdt_mZTTl6w.html In any case, drawbacks and benefits to both approaches. They can both be implemented well and horrible. Plus, personal taste etc'.
@dimitryselin42257 күн бұрын
@@amantinband I want to add some text to this big comment. In big applications we ussualy work with diffrent nuget-packages, call low-level code of c/c++ dll from c#, send http-queries and so on. Often all this stuff generate exceptions (and some authors of libraries say that exception handling is the normal flow of using their packages). So in that case you need handle both: error codes and standard c# exceptions. These approaches lead to complicated error handling, lots of exception hadling code and of course bugs. And last but not least - your entire architecture will strong link with lib. (I hope you know that authors can change package license, stop maintenance and even do what happened to the package "moq") P.S. This is not about you Amantin))
@MahmoudSaed987 күн бұрын
source code please
@amantinband7 күн бұрын
Hey Mahmoud, the source code is available for patrons and members. The description has all the relevant links
@krccmsitp28847 күн бұрын
3:37 I concur. In domain-centric, i.e. non-CRUD applications/modules, exceptions don't fit well.
@tchial07 күн бұрын
Simple and good analysis of what approach to choose.
@harrisonwell17197 күн бұрын
I found ErrorOr Adds a lot of unnecessary code
@amantinband7 күн бұрын
That's the main drawback of being explicit
@parlor31157 күн бұрын
Not really, if you look closely, it's as much code as the exception approach. But I prefer this approach because it's more readable (the return type tells you everything about the method)
@petherpettersson61526 күн бұрын
@@parlor3115 Not really, since in every endpoint you will need to add code to handle if you should return the result, or the error if there is anything. Whilst a global exception handler is just that, global, so you do not have to do anything special for it to work. So requiring 5 to 10 extra rows of code is not as much code as no extra rows. *Edit* And then we have the extra try+catch code on top of that...
@parlor31156 күн бұрын
@peth You only handle at the level you want to access the success data in and you have to handle either the exception (try catch) or the return. Otherwise, you'll just let the return propagate as is. And in case of generic and expected errors (validation, record not found, ...), then you'll return those at the last step (at the action method), where an after middleware is dispatched that will check the response and handle it accordingly just like a global error handler. With this, you'll be right the same amount of code while saving on performance.
@DavidSmith-ef4eh7 күн бұрын
How would you translate the error messages on apis with multi language support?
@krccmsitp28847 күн бұрын
How would you do that with exceptions?
@tchial07 күн бұрын
I would probably create a service class that returns a message according to the language. And have message templates.
@krccmsitp28847 күн бұрын
@@tchial0 there's no difference in this
@rankarat7 күн бұрын
Are you also responsible for the client-side development? If so, consider creating a shared project to house a mapping system and resource files. The API will return a code indicating a problem, which will act as a key in the resource file. This approach will facilitate easy management of multiple languages.
In my experience, when you don’t use global handlers and exceptions as your default error handling mechanism, the code becomes a lot more complex, you would just write a ton of meaningless code just to propagate the error up the call stack - exactly what exceptions do when you forget about error handling, and you get a nice stacktrace in that case so you can find the cause of your error easily. Once you do, you can add adjust the error handling. That’s much better than relying on programmers always doing a correct handling and adding all the context info after each function call. That’s not naive approach, that’s very practical approach
@NoTarantino8 күн бұрын
Hi I am trying to learn dotnet. Think you are a great at giving explanations. But it would have be great to have links to repos for each lesson. I get stressed out not knowing if it will build or not. It can be a bit unclear of were you are watch list etc. Your videos probably have different setting and different versions.
@NoTarantino8 күн бұрын
Ah the playlist was in reverted order😅
@AshrafSada9 күн бұрын
For windows users, dotnet sln .\solutionFileName.sln add (ls -r **/**/**.csproj)
@mstislavmaslennikov32611 күн бұрын
Thank you for the nice review and demonstration!
@RealmOfCode11 күн бұрын
You're going too fast... Sorry.
@rayawwad29212 күн бұрын
It’s not that hard tho
@RealmOfCode2 күн бұрын
@@rayawwad2921 Oh! you're one of those...
@xybersurfer12 күн бұрын
any tips on how to do global error handling in Blazor? ErrorBoundary doesn't seem to catch everything
@MartinoBordin12 күн бұрын
Can we use it also for grpc services?
@ashoktandan237212 күн бұрын
why scoped for IDBConnectionFactory class?
@Buutyful12 күн бұрын
perfect video 10/10
@pierre936812 күн бұрын
Bad description of the problem. Task.WhenAll is a method that returns TASK, so use await same as for any task.
@afgone12345613 күн бұрын
So if a client comes back with a traceid how would a developer find the real issue for that request? Are you saying we need to log it to db or something using the error endpoint?
@ashu376913 күн бұрын
which tool you are using and how to set this up?
@harrisonwell171913 күн бұрын
why you don't respond to questions in the comments?
@AslamNazeerShaikh13 күн бұрын
Not sure if this is 100% true or not ?! 🤔
@amantinband13 күн бұрын
I can’t always keep up with all the comments.. sorry if I missed your previous message 🙏🏼
@turcanuioangeorge475013 күн бұрын
What is the tool you used to highlight code? Or is it just done in post production
@amantinband13 күн бұрын
Presentify
@felipecosta988913 күн бұрын
Great content. One question. Is it best practice to throw exceptions in my code and catch them with global error handling? Or is it better to throw only exceptions that cannot be predicted?
@amantinband13 күн бұрын
This is exactly next Monday’s video
@SerafimMakris13 күн бұрын
Good job. clean code as usual. i Hate you :D :D :D Ty @amantinband
@solvestation13 күн бұрын
Great tutorial. I would like to ask if the implementation is usable in a .net 8 MVC project? Thank you @Amichai
@amantinband13 күн бұрын
Yep
@solvestation13 күн бұрын
@@amantinband Thank you
@gopimech203013 күн бұрын
Nice video on global exceptions, but for Global Exceptions we inherit from IExceptionHandler which provides more flexibility by implementing multiple exception handlers from it. Do you say this approach is more flexible and recommended?
@amantinband13 күн бұрын
IExceptionHandler is more flexible. But comes with more boilerplate. If you need the flexibility, it's superior to an error handling endpoint
@obinnaokafor625213 күн бұрын
What icon plugin are you using in your VS Code?
@amantinband13 күн бұрын
vscode-icons
@vuhoang590313 күн бұрын
I have a question, when applying EF Core or other ORM in our .NET Clean Architecture project then the classes that we perform the mapping on is the entities in the Domain layer or what?
@10Totti13 күн бұрын
Great tutorial, but why not use a new IExceptionHandler abstraction for managing exceptions ?
@amantinband13 күн бұрын
I would choose IExceptionHandler over this approach for larger applications that need the modularity. For smaller apps, I personally prefer this approach
@Eirenarch13 күн бұрын
I don't understand the value of separate endpoint. Why not have a middleware that catches exceptions discriminates by their types, builds the appropriate ProblemDetails and writes it to the response
@amantinband13 күн бұрын
Both are solid choices. It mostly comes down to preference
@Dustyy0113 күн бұрын
There is no benefit in using the route approach like this. Normally you handle the exception using the IExceptionHandler interface and if you return false in the TryHandleError method, the route will receive the exception to further process (e.g. show a nice error html page). If you return true your exception is handled. I dont know any other reason why you want to use the route instead of the Interface in a plain API
@Fikusiklol6 күн бұрын
@@Dustyy01 I agree aswell. If you want granular exception handling - IExceptionHandler is the way to go. However for easy/small services both approaches mentioned above are just fine.
Пікірлер
Great Videos, Please can you do one on Composition and Or with Strategy Pattern, I have been struggling with these for months.
is that video speed up a little or do you have some sort of voice adjustment going on?
Ive been using this approach for a long time now. What i like about it, is that it forces you to deal with some code smells 1. exceptions are for exceptional situations - for example, a method parameter should under no circumstance be a null, but somehow is - the program cannot continue handling the request 2. explicitly deal with specific error situations - how do we handle situation X? how do we handle situation Y?
Using exceptions for logic branches that you KNOW how to handle without exceptions, such as by returning a suitable response, is not a good idea. It creates a different user experience in most cases, and it creates far more overhead in terms of error logging, monitoring, unit testing, etc. Nothing worse than a unit test, or functional/integration test, that has to say "did this throw an exception?" .. "yes, test passed" ... just stupid :)
I generally agree and have videos on the channel relaying this exact point. The truth is in the middle. Both approaches have great benefits and drawbacks. I’m demonstrating what I would personally use for a small-medium, mostly CRUD app when looking to get things up and running as fast as possible.
Very powerful tool. Yoou have convinced me this is a tool I need. THANK YOU.
Exception should only ever be used IF AND ONLY IF ITS THE ONLY OPTION. Exceptions are incredibly memory and processing intensive and should be reduced as much as possible so even suggesting to use it just because it’s simpler is one heck of a quick way to make people fail an interview
Sounds like you’ll enjoy this video: Exceptions are evil. This is what I do instead. kzread.info/dash/bejne/ZJydrdt_mZTTl6w.html
Hi Amichai, I think you missed another solution which is also used by Vaughn Vernon. Have you considered creating a separate value object that holds the reference ids? For example "record HostMenu(HostId hostId, MenuId menuId);" which then can be easily used in OwnsMany() and you can again define each with HasConversion(). I think this approach is easier to understand and depending on UL, it can bring better clarity. For example, in IDDD book VV is using a value object CommittedBacklogItem within the Sprint aggregate and that value object is used in a HashSet inside the Sprint object. I really like that approach because it also brings a good understanding of what that actually mean for the sprint. It's not just a list of backlog items but they are actually backlog items committed for the sprint. Same goes for ScheduledBacklogItem within the Release aggregate. Also, in version 8 the EF Core team introduced a ComplexProperty which is really good for such cases, though, it's still very limited and they cannot yet properly be used for collections or keys but once they improve them it will be really cool feature to use.
Great video! Thank you for your effort! What software do you use for creating these boxes and arrows as you drag your mouse?
Presentify
Talking about DDD, what you think about to never have conditionals in application services? I see you do "productRepository.Exists()" and checking if product exists, if it exists you create the review if not you throw. To not have logic like that in app service you could do that your product domain model creates the review, like "product.CreateReview()". So in app service you get the actual product doing "productRepository.getProduct(ProductId)" and you get the product or else throw, then you create the review using that product.
What’s the motivation for not having conditionals in application services?
Why not just return either the record, or 200 OK with empty list/no record, if it was not found? Is that not okay?
Both approaches are good and valid. Personally, if I get to choose, I return 404 for *parent* resource not found, and 200 ok and empty list for collection not found/empty
Does the same principle apply to other languages (python, php for example) that have exceptions and can you have an equivalent to ErrorOr in those languages?
I generally disagree with throwing exceptions in non-exceptional circumstances. However, in this example I more strongly disagree with throwing an exception in a service layer that contains an HTTP response code. You are assuming you will always use your service layer with a web-based API, and tying it to this usage. A service layer should be just that - services. An API layer, such as WebAPI in this case, should have the responsibility of returning the appropriate HTTP response code.
Please note that we’re talking about simple, small to medium applications that are mostly CRUD. I share your opinion for larger, more complex applications. For the smaller apps, personally, I’d choose the higher coupling, higher cohesion approach and refactor if needed
I do like ErrorOr I use it in all our projects
The best, concise, to-the-point, relevant and CLEAR communication!! above all, I really like the way you kept on showing the Diagram and linked it with the Code, that is where we are! I've never seen any .NET video instructors making such a clear and crisp connection to the Infographic vs Code!! great stuff! will definitely cover your entire course!! This is coming from a full stack .NET developer who has been dirtying hands for the last 15 years!! bravo! more power to you mate! love from Australia!
"Repositories go into either the application or domain layers" I believe their implementation goes into the infrastructure layer, but their definition (if you're working with interfaces/headers/protocols) belongs to the domain layer. This keeps the domain from being dependent on the infra layer, while still making use of it, often through dependency injection
What I can't really buy on the cons of Exceptions is the cost of them, sure, it has some resource cost, but who designs a product to do the bad incorrect stuff all the time? There's supposed to be validation on input on the frontend, the one on backend is just a safeguard, so will have no Exceptions there if the frontend has done it's job, so then the only exceptions coming are the ones where something goes bad during processing?
When using exceptions for flow control, by definition you’re using exceptions for flows that are not exceptional. Depending on the scale and requirements of the app, this can be significant
Thank you very much. Maybe Next Video how you would log and which framework you would use.
It’s coming
discount code invalid.
Why are you separating command and query outside of IAuthenticationService? No code outside of the implementation cares. You're introducing something and a LOT of code that doesn't matter. The implementation of authentication's repository (maybe IAuthenticationRepository) might care because there is a read side and a write/transaction side, but not at the front end or what should be a very thin, single line, of code in the controller. Oh, and what happens if login requires a counter update to restrict failures every n minutes? Also, even query commands will/might update the log database, but I guess that doesn't count. Sorry for the rant.
Learnt something new. Thanks so much
One thing I disagree with is ever returning a 404 on a List (collection) endpoint. I'm not sure why your List asked for a product Id. But a list should return an empty collection if no resources match the predicate.
If it's up to me, I choose 404 for parent resource not found, but both are fine and valid approaches
@@amantinband Oh so you are listing some child resources of a product. I guess I could see returning a 404 in the case of the missing product.
That's funny, I completely and fundamentally disagree. IMO, if you have a simple application, you can use return codes, but complex applications with lots of shared code and deep stacks of function calls benefit enormously from Exceptions. Exceptions simplify error handling and code readability MASSIVELY over returning error codes. Exceptions were a response to return codes' lack of scalability because return codes require that EVERY time a function is called, whatever calls it has to have logic to handle the error condition right there. Exceptions allow you to simply pass the error up the chain until something that cares or knows what to do will actually handle it. Further, exception handling is done outside the general flow of logic so someone reading the code can actually understand what is 'supposed' to be happening and there's no chance that anything UP the stack is going to continue executing in a faulty state. On top of that, IMO, it's a TERRIBLE idea to have multiple outputs from a given function. It's bad enough to have the possibility of null or an object, but to then throw in the possibility of a third type to check and unpack the result of every function call? How is that scalable? It's a rat's nest of error handling! That's the beauty of an 'out' parameter is you can have the function return a specific type of result and then use the object if it's valid or else handle the case of it not being valid. The other great power of an Exception is that you can add context as the stack unwinds at the levels where it makes sense. Return codes can only change the context and you might lose vital information about what happened in the error situation. You're basically left with the choice of a user being told that there was a divide by zero error OR that the review didn't get added with no information about WHY. For instance, in a complex application a UI action will likely start a cascade of function calls splitting off into different directions to handle the different subtasks associated with with whatever the user just asked for. An exception deep in the bowels of that can say there was a divide by zero error, but then that can propagate to a failure to generate a star rating value which can then be caught closer to the UI level and told that the review couldn't be added. When you're building the message for the user and the message for the log, you'll have different info you can use to generate useful information in both contexts right at your fingertips without generating multiple log entries that you have to then piece together. IMO, you should throw Exceptions if the code you're in can't handle the current logical situation. For instance, adding a review to a product that doesn't exist. But if the code you're in CAN handle the situation, like perhaps you're adding an item to a list of items that share some property, but nothing has been added with that particular property yet, you should create the list for those items--no need for an exception or return code. Not using exceptions and relying on return codes is going backwards. And returning multiple data types from a function has always been a really bad idea from a readability and usability standpoint. The only real use case for return codes is in headless programs or highly performant libraries; but you better be sure the tradeoff in readability and debuggability is worth it.
Thanks for taking the time to share your thought and experience. My opinion around this topic is shaped from suffering bad implementations of exceptions for flow control in numerous large complex projects within Microsoft. I elaborate my opinion in more detail in this video: kzread.info/dash/bejne/ZJydrdt_mZTTl6w.html In any case, drawbacks and benefits to both approaches. They can both be implemented well and horrible. Plus, personal taste etc'.
@@amantinband I want to add some text to this big comment. In big applications we ussualy work with diffrent nuget-packages, call low-level code of c/c++ dll from c#, send http-queries and so on. Often all this stuff generate exceptions (and some authors of libraries say that exception handling is the normal flow of using their packages). So in that case you need handle both: error codes and standard c# exceptions. These approaches lead to complicated error handling, lots of exception hadling code and of course bugs. And last but not least - your entire architecture will strong link with lib. (I hope you know that authors can change package license, stop maintenance and even do what happened to the package "moq") P.S. This is not about you Amantin))
source code please
Hey Mahmoud, the source code is available for patrons and members. The description has all the relevant links
3:37 I concur. In domain-centric, i.e. non-CRUD applications/modules, exceptions don't fit well.
Simple and good analysis of what approach to choose.
I found ErrorOr Adds a lot of unnecessary code
That's the main drawback of being explicit
Not really, if you look closely, it's as much code as the exception approach. But I prefer this approach because it's more readable (the return type tells you everything about the method)
@@parlor3115 Not really, since in every endpoint you will need to add code to handle if you should return the result, or the error if there is anything. Whilst a global exception handler is just that, global, so you do not have to do anything special for it to work. So requiring 5 to 10 extra rows of code is not as much code as no extra rows. *Edit* And then we have the extra try+catch code on top of that...
@peth You only handle at the level you want to access the success data in and you have to handle either the exception (try catch) or the return. Otherwise, you'll just let the return propagate as is. And in case of generic and expected errors (validation, record not found, ...), then you'll return those at the last step (at the action method), where an after middleware is dispatched that will check the response and handle it accordingly just like a global error handler. With this, you'll be right the same amount of code while saving on performance.
How would you translate the error messages on apis with multi language support?
How would you do that with exceptions?
I would probably create a service class that returns a message according to the language. And have message templates.
@@tchial0 there's no difference in this
Are you also responsible for the client-side development? If so, consider creating a shared project to house a mapping system and resource files. The API will return a code indicating a problem, which will act as a key in the resource file. This approach will facilitate easy management of multiple languages.
@@krccmsitp2884 Let's say (or code, lol): "var errorMessage = cultureService.GetErrorMessageById(errorMessageId, param1, ...)"
Why don't use Record for value objects?
In my experience, when you don’t use global handlers and exceptions as your default error handling mechanism, the code becomes a lot more complex, you would just write a ton of meaningless code just to propagate the error up the call stack - exactly what exceptions do when you forget about error handling, and you get a nice stacktrace in that case so you can find the cause of your error easily. Once you do, you can add adjust the error handling. That’s much better than relying on programmers always doing a correct handling and adding all the context info after each function call. That’s not naive approach, that’s very practical approach
Hi I am trying to learn dotnet. Think you are a great at giving explanations. But it would have be great to have links to repos for each lesson. I get stressed out not knowing if it will build or not. It can be a bit unclear of were you are watch list etc. Your videos probably have different setting and different versions.
Ah the playlist was in reverted order😅
For windows users, dotnet sln .\solutionFileName.sln add (ls -r **/**/**.csproj)
Thank you for the nice review and demonstration!
You're going too fast... Sorry.
It’s not that hard tho
@@rayawwad2921 Oh! you're one of those...
any tips on how to do global error handling in Blazor? ErrorBoundary doesn't seem to catch everything
Can we use it also for grpc services?
why scoped for IDBConnectionFactory class?
perfect video 10/10
Bad description of the problem. Task.WhenAll is a method that returns TASK, so use await same as for any task.
So if a client comes back with a traceid how would a developer find the real issue for that request? Are you saying we need to log it to db or something using the error endpoint?
which tool you are using and how to set this up?
why you don't respond to questions in the comments?
Not sure if this is 100% true or not ?! 🤔
I can’t always keep up with all the comments.. sorry if I missed your previous message 🙏🏼
What is the tool you used to highlight code? Or is it just done in post production
Presentify
Great content. One question. Is it best practice to throw exceptions in my code and catch them with global error handling? Or is it better to throw only exceptions that cannot be predicted?
This is exactly next Monday’s video
Good job. clean code as usual. i Hate you :D :D :D Ty @amantinband
Great tutorial. I would like to ask if the implementation is usable in a .net 8 MVC project? Thank you @Amichai
Yep
@@amantinband Thank you
Nice video on global exceptions, but for Global Exceptions we inherit from IExceptionHandler which provides more flexibility by implementing multiple exception handlers from it. Do you say this approach is more flexible and recommended?
IExceptionHandler is more flexible. But comes with more boilerplate. If you need the flexibility, it's superior to an error handling endpoint
What icon plugin are you using in your VS Code?
vscode-icons
I have a question, when applying EF Core or other ORM in our .NET Clean Architecture project then the classes that we perform the mapping on is the entities in the Domain layer or what?
Great tutorial, but why not use a new IExceptionHandler abstraction for managing exceptions ?
I would choose IExceptionHandler over this approach for larger applications that need the modularity. For smaller apps, I personally prefer this approach
I don't understand the value of separate endpoint. Why not have a middleware that catches exceptions discriminates by their types, builds the appropriate ProblemDetails and writes it to the response
Both are solid choices. It mostly comes down to preference
There is no benefit in using the route approach like this. Normally you handle the exception using the IExceptionHandler interface and if you return false in the TryHandleError method, the route will receive the exception to further process (e.g. show a nice error html page). If you return true your exception is handled. I dont know any other reason why you want to use the route instead of the Interface in a plain API
@@Dustyy01 I agree aswell. If you want granular exception handling - IExceptionHandler is the way to go. However for easy/small services both approaches mentioned above are just fine.