When To Validate and When To Throw Exceptions?

  Рет қаралды 9,518

Ardalis

Ardalis

Күн бұрын

Пікірлер: 41
@loam
@loam Жыл бұрын
Wow, new channel for me on C#, and I like it already, seems promising.
@Ardalis
@Ardalis 10 ай бұрын
Hope you enjoy it!
@codecomposer88
@codecomposer88 8 ай бұрын
Hi @Ardalis. Would you do validation or guard clauses when we're talking specifically a modular monolith architecture in regards to inter-module communication? I have a gut feeling that validation with a result type should be default way to go in order to prevent throwing exceptions between modules even though it's technically all happening at the domain layer.
@Ardalis
@Ardalis 8 ай бұрын
Inter-module means it’s spanning bounded contexts, so it’s not all domain layer. It would be like your code calling out to GitHub API or similar. You should treat the other modules like separate apps built by separate orgs, and only rely on the contract exposed. That said I’m not sure whether I’d prefer an exception or validation in that case, offhand. If the contract is exposing Result types I’d probably use those. If not I’d use exceptions. If it was new functionality and I could choose, I’d lean toward Result as it offers more flexibility.
@codecomposer88
@codecomposer88 8 ай бұрын
@@Ardalis Makes sense, thanks! Agree on going for result types in the contracts as much as possible.
@carlosirias4474
@carlosirias4474 8 ай бұрын
Great content! Thanks for sharing your knowledge!
@Ardalis
@Ardalis 8 ай бұрын
Glad it was helpful!
@surajshaha5819
@surajshaha5819 Жыл бұрын
I like this hairstyle @ardalis.. videos are as usual informative and helpful..
@Ardalis
@Ardalis 10 ай бұрын
Thanks!
@PticostaricaGS
@PticostaricaGS Жыл бұрын
It’s important to mention that user-entry validations must be implemented in a way that it does not require to even do a roundtrip when possible.
@Ardalis
@Ardalis 10 ай бұрын
Yes, that way they improve user experience. But you still need to re-validate on the server, for security reasons.
@islandparadise
@islandparadise 4 ай бұрын
Love this video, thanks! Question on the Result UpdateName(): Here I see that the Validation Result method is in the Entity. However if the field Name is used in several Entities, would it be practical to avoid copy-pasta by strongly typing the Name & put the validation logic there? Perhaps Name may not be the best example for my scenario, but Email could appear in multiple Entities?
@Ardalis
@Ardalis 3 ай бұрын
Yes, definitely. Using more Value Objects (strongly typed name) will reduce the need for validation in your entity. Ideally down to zero.
@islandparadise
@islandparadise 3 ай бұрын
@@Ardalis I’m on the right track, yay! Thanks! 😊
@flipdoubtful
@flipdoubtful Жыл бұрын
I see lots of links in the description, but which is "the" link to the article you mention at the beginning of the video? Maybe I'm old school, but I often prefer to read rather than watch.
@Ardalis
@Ardalis Жыл бұрын
This one: ardalis.com/guard-clauses-and-exceptions-or-validation/
@melihyilman8803
@melihyilman8803 Жыл бұрын
Thanks! Happy coding 💻
@Ardalis
@Ardalis 10 ай бұрын
You're welcome!
@RichardJohn86
@RichardJohn86 Жыл бұрын
How was the validator triggered?
@Ardalis
@Ardalis Жыл бұрын
It's done automatically by Fast Endpoints: fast-endpoints.com/docs/validation
@pilotboba
@pilotboba Жыл бұрын
@@Ardalis Yep, fast endpoints has some magic. :)
@DiegoFernandez-cy3fr
@DiegoFernandez-cy3fr Жыл бұрын
Good video, good hat! Thanks
@Ardalis
@Ardalis 10 ай бұрын
Heh, thanks! :)
@lpsoldier357
@lpsoldier357 Жыл бұрын
How can I call the http requests like you're doing in visual studio? Is this an extension? Thanks!
@Ardalis
@Ardalis Жыл бұрын
Support for .http files is a new feature in the latest version of Visual Studio 2022.
@lpsoldier357
@lpsoldier357 Жыл бұрын
@@Ardalis Awesome, thanks!
@piotrkowalski3460
@piotrkowalski3460 9 ай бұрын
Isn't it better to throw exceptions in the domain model in this case? It would mean that developer forgot to apply input validation (exceptional situation)
@Ardalis
@Ardalis 9 ай бұрын
Yes that’s exactly what I recommend and why. Guard clauses and exceptions in the domain, validation in the application.
@piotrkowalski3460
@piotrkowalski3460 9 ай бұрын
@@Ardalis when would you use Result in the domain instead of exceptions? I guess it could be used for control flow in the use-case layer. However with validations it never happens.
@Ardalis
@Ardalis 9 ай бұрын
@@piotrkowalski3460 I use Result when there are non-exceptional ways in which the operation might fail. For example, a service might try to transfer money between accounts, but the sending account lacks sufficient funds. That might result in a Result describing the failure. Or one of the accounts might not exist - Result.NotFound might be appropriate. Usually validation in the application checks the structure of the request, but doesn't necessarily check the business logic or the existence/state of the underlying domain elements. Result within the domain could do so.
@pilotboba
@pilotboba Жыл бұрын
I would also suggest you could also remove the primitive obsession. Make the ContributorName a class that encapsulates the rules with a Create() method that returns a Result. Then your Contributor class would accept a ContributorName rather than a string.
@stefan-d.grigorescu
@stefan-d.grigorescu 11 ай бұрын
Agreed, probably this is the best way to encapsulate rules in a consistent way
@Ardalis
@Ardalis 10 ай бұрын
Yes, adding value objects which can perform their guards in their constructor can certainly simplify entity mutation methods, 100%. I have a video in my queue about exactly this!
@obiwanjacobi
@obiwanjacobi 10 ай бұрын
You duplicated the validation logic between the 'front door' (API entry point) and you domain model. Would you suggest making a single validation method specific for contributor name that is reused throughout the code? If so, how would you manage this dependency in these two different places.
@Ardalis
@Ardalis 10 ай бұрын
Possibly. In such a simple example there wasn't much "drift" between the API contract and the domain model, but in a real application there can be. In which case having unique validation rules/validators at the API and domain model makes sense. I think as long as things are literally the same, you might get some benefit from reusing validation logic (or validators). And also you might get some benefit from low-level validators that can be used in many places, like a string validator called ValidName that can be used for any number of Name fields, for instance. You might still use unique validators at the API and domain level, but they might both internally use a NameValidator, for example. And of course moving toward more value objects and fewer primitives (ints/strings/etc) at the domain model level also helps.
@joga_bonito_aro
@joga_bonito_aro Жыл бұрын
Wouldn't it be better to write a validtor using the fluentvalidation lib and reuse the validator, instead of reimplementing the validtor with multiple if statements? I mean, you have it already, why not reusing it?
@Ardalis
@Ardalis Жыл бұрын
The validator works on an object; the method accepts inputs and should only modify the state of the object it’s on if those inputs are valid. To use the validator you would need to create an object first (or modify the state of the current one), then validate, and if you modified the current object, roll back if invalid. Also most objects have many properties but this method on it checks one of them, so using the validator may do a lot of extra work. It’s true we should find a way to not duplicate the logic though. Stay tuned.
@joga_bonito_aro
@joga_bonito_aro Жыл бұрын
Wouldn't something like this work: public class CreateContributorNameValidator : Validator { public static readonly CreateContributorNameValidator Instance = new CreateContributorNameValidator (); public CreateContributorNameValidator () { RuleFor(x => ...); } } public class CreateContributorValidator : Validator { public CreateContributorValidator () { RuleFor(x => x.Name) .UseValidator(CreateContributorNameValidator.Instance); } } With this you have the same logic and no new instances will get created constantly. Just a quick thought though.
@VangelisMatosMedina
@VangelisMatosMedina 11 ай бұрын
If we decide to change the minimum value now we have to change in 02 places......
@Ardalis
@Ardalis 10 ай бұрын
Possibly, yes. If you like, you can always declare this in a constant and reference it from both locations. It's frequently the case for data-backed properties that you need to define the data size (EF configuration or SQL scripts or VS Database Project or somewhere) and validation and guard clauses, so constants like this or pretty commonplace.
5 Rules For DTOs
17:56
Ardalis
Рет қаралды 46 М.
"Don't Throw Exceptions, Use A Result Pattern" is BAD ADVICE!
19:22
Codewrinkles
Рет қаралды 3,7 М.
The evil clown plays a prank on the angel
00:39
超人夫妇
Рет қаралды 53 МЛН
The Best Band 😅 #toshleh #viralshort
00:11
Toshleh
Рет қаралды 22 МЛН
We Attempted The Impossible 😱
00:54
Topper Guild
Рет қаралды 56 МЛН
My FAVORITE Error Handling Technique
16:01
ArjanCodes
Рет қаралды 46 М.
The New Option and Result Types of C#
15:05
Nick Chapsas
Рет қаралды 84 М.
When do I throw an Exception or Return an Error
12:11
Gui Ferreira
Рет қаралды 4,6 М.
Exceptions Are Extremely Expensive… Do This Instead
17:15
Milan Jovanović
Рет қаралды 50 М.
Using Ardalis Specifications with EF Core 8
13:06
Ardalis
Рет қаралды 8 М.
C# Minimal APIs Quickly Get Messy - Clean Them Up!
12:41
Zoran Horvat
Рет қаралды 9 М.
Exceptions are evil. This is what I do instead.
24:41
Amichai Mantinband
Рет қаралды 22 М.
Building Complex Objects in a Simple Way with C#
12:19
Gui Ferreira
Рет қаралды 10 М.
This Is My FAVORITE Error Handling Class
28:57
Philipp Lackner
Рет қаралды 36 М.
Implementing the Result Pattern In ASP.NET API
16:50
Codewrinkles
Рет қаралды 6 М.
The evil clown plays a prank on the angel
00:39
超人夫妇
Рет қаралды 53 МЛН