When To Throw Exceptions?

  Рет қаралды 1,716

Codewrinkles

Codewrinkles

Күн бұрын

Пікірлер: 34
@richardaubin1951
@richardaubin1951 4 ай бұрын
I'd like to see the result pattern video along with best practices on using the pattern.
@nirajchandrajoshi
@nirajchandrajoshi 4 ай бұрын
Please make a video on result pattern
@HarleyPebley
@HarleyPebley 4 ай бұрын
5:12 Here's an example of exceptions causing a performance problem: my team was writing a winforms application for a business partner and we were mandated to use a UI library written by one of this partner's teams. During validation they complained that the application while idle caused CPU usage to be around 30%. After some digging, I found their library was throwing an exception *on every pass through the Windows dispatcher loop.* They didn't want to believe that was the problem so I rewrote a couple methods to change the exception to a return value and the idle CPU usage dropped to undetectable. 15:20 Maybe I missed something but I didn't get why use of the result pattern in the domain layer would be bad.
@balazs.hideghety
@balazs.hideghety 4 ай бұрын
Exceptions, unless you decide to catch them to manage flow are great. The result pattern has its downside: it clutters the caller, and imagine you are in an invalid state, but you forget to check it at the caller, then at the caller's caller...and well you end up easily with some stale data persisted. The 30% slowdown benchmark is something invalid, I mean if exceptions are used as they are meant to, there's little to ZERO performance penalty - e.g. you always do UI side validation, then server side is just an extra countermeasure, and so are other checks in the domain layer. This is why using exceptions in general is safe.
@Codewrinkles
@Codewrinkles 4 ай бұрын
Thank you for sharing your tought. Very interesting scenario. Regarding your final parapgraph I didn't say that using the result pattern in the domain is bad. I just think that If an app is set up properly (as described in the video) throwing exceptions in the domain actually makes sense as it meets all the definitions and conceptual setup of what an exception is and when should it be thrown. I prefer to throw exceptions in the domain as a last resort because of two reasons: 1. It happened quite a bit the the domain library was used and re-used like a regular library for other applications and purposes and from this point of view I think it's not okay (at least for me) to impose some programming patterns to the library consumers 2. What I mentioned in the previous paragraph. If there's no possibility to do anything else then putting the app in an invalid state, then I think it's appropriate to throw an exception because this situation is truely exceptional.
@HarleyPebley
@HarleyPebley 4 ай бұрын
​@@balazs.hideghety > The 30% slowdown benchmark is something invalid,... Not sure what you mean by "invalid." I related an actual, real-life scenario I had to address where exceptions were causing an actual performance problem. > I mean if exceptions are used as they are meant to Right, the point was, they weren't being used in a reasonable way. They were used for the typical flow path inside the Windows event dispatcher, that's executed 1000s of times a second. Exceptions are not expensive to expect (try/finally/catch). They are very expensive (relatively speaking) when they're actually thrown. They should be used for really exceptional things, not things one would expect in the normal course of execution. > The result pattern has its downside: it clutters the caller,... And as pointed out in the video, the downside of using exceptions is they're hidden. The API doesn't indicate that it'll happen at all. It's implicit knowledge the user of the API needs to know and account for. Since it's hidden, it's easy for the caller to forget to deal with it. At least with the result pattern, it's in the user's face that they need to deal with it.
@HarleyPebley
@HarleyPebley 4 ай бұрын
​@@Codewrinkles > Very interesting scenario. Yeah, it was a big face-palm moment for me when I saw what they were doing. > It happened quite a bit the the domain library was used and re-used like a regular library... Ok, sounds like you don't want to force an extra dependency on the users of the domain. I can see situations where that'd make sense. Thanks!
@N3PatHYA
@N3PatHYA 4 ай бұрын
Thank you for this video. I'd also like to see the result pattern video.
@user-dc9zo7ek5j
@user-dc9zo7ek5j 4 ай бұрын
I have few things to comment. 1. The beginning of the video there were some strange sounds, maybe something was forgotten. 2. Exceptions are way cheaper than possible errors when implemented correctly. The problem is that the framework logic relies a lot on logic that is using exceptions, this slows things down considerably when exceptions are not... well, exceptional, rather validational. We all know by now that exceptions are the standard descrete error handlers. This was probably done because programming languages were still evolving when it first popped up. 3. Although Result pattern is good, it does not solve the issue of exceptions, just make errors explicit. They are still discrete because you cannot see what are the possible errors, unless you do each error as a class and do OneOf style (which is incredibly annoying). The validations are always present and done twice which reduces performance (once at the callee, and when returned to the caller). Also as more logic relies on the Result pattern, the chain of calls can introduce an avalance of possible returns from deep within modules (returns something that was returned from within, giving the possibility of the Result to contain any error). 4. Functions that have invalid handling + core logic violate SoC. The solution is to redesign the core framework (not impossible but impractical) to use more static analysis, and to lift the responsibilities as high as they can to make the validations obtrusive. For example, Enumerable.Max(int[] numbers) => Enumerable.Max(NotEmptyArray numbers), the NotEmptyArray will have a static function that will either give itself with the type within or it will throw/result early. This removes the need for logic to defend itself from invalid state, and also removes most of the cases where exception are needed. It also ensures consistency and allows for other logic to use what is already built.
@Codewrinkles
@Codewrinkles 4 ай бұрын
Some very valuable toughts here. Thanks for contributing!
@danurarya0823
@danurarya0823 4 ай бұрын
Very well explained, thanks for always go more in depth expalanation in every video appreciated it
@Codewrinkles
@Codewrinkles 4 ай бұрын
Glad it was helpful!
@vitaliymandzyak281
@vitaliymandzyak281 4 ай бұрын
Thanks for the video, that would be nice you can create one with Result pattern And I have a small question here: exceptions vs business process, line 24, what if account is null? (lets imagine that repo does not throw an exception if requested entity was not found) so what should we do? throw a NullRefferenceExcpetion? throw a some kind of custom exception which points that account was not found, or use Result pattern?
@wolecharlesjob8255
@wolecharlesjob8255 4 ай бұрын
Great Video.thanks
@Codewrinkles
@Codewrinkles 4 ай бұрын
Glad you liked it!
@rafapioli75
@rafapioli75 4 ай бұрын
Great explanation! Please, make a video showing a useful example of result pattern. I'm not yet convinced that this is the way to go because you transfer the responsibility to handle the return to the caller.
@Codewrinkles
@Codewrinkles 4 ай бұрын
I personally prefer the result patter, but I am not part of the crowd that says it's the only right way to do it. For me it's also a valid approach to just throw the exceptions and have some global exception handling logic that turns those into HTTP response errors.
@rafapioli75
@rafapioli75 4 ай бұрын
@@Codewrinkles Nowadays, I'm throwing custom exceptions. But I'm open and looking for a better approach. I didn't have any performance impact yet because my systems are small.
@veniaminbalan
@veniaminbalan 4 ай бұрын
Thanks for the video, great explanation, but my question is: is it legitim to throw exception from repository and at the infrastructure level ?
@Codewrinkles
@Codewrinkles 4 ай бұрын
Well, EF or whatever you use to interact with your databse will throw exceptions. The way I do it is I usually catch them in the handler and trasform them into a result. Or they are caught only by the global exception handler. I didn't find myself very often in situation where I'd want to throw exceptions myself iin the repository.
@user-uo7ch2lf3z
@user-uo7ch2lf3z 4 ай бұрын
A video on Result pattern would be greatly appreciated.👍
@Codewrinkles
@Codewrinkles 4 ай бұрын
Noted!
@balazs.hideghety
@balazs.hideghety 4 ай бұрын
no, no, no - plz. no more result pattern video. people, you're choosing the dark side without understanding how minimal to almost zero performance costs exceptions have if they're implemented with all the other things around that a normal software should have!
@dabest9843
@dabest9843 4 ай бұрын
Result Pattern video, pls.
@zoranProCode
@zoranProCode 4 ай бұрын
Please make a video how to create and use result pattern.
@ashishmaurya3669
@ashishmaurya3669 4 ай бұрын
Sonar complain either log or rethrow exception. What's your opinion on that?
@Codewrinkles
@Codewrinkles 4 ай бұрын
It depends where exactky you have your exception based on the scenario in the video. Scenario 1: you shouldn't have any type of exception there. Just return a bad request if validation fails Scenario 2: There shouldn't be an exception at all = refactor to result pattern and return bad request Scenario 3: Eventually you'll need to turn the exception into error result from the API. So, probably you'd want to catch it with your global exception handling mechanism, log it (you always need to log exceptions) and then turn it into an error response in your API. Sonar will not complain anymore.
@z0nx
@z0nx 3 ай бұрын
Didn't expect that last example to be throwing exceptions. Isn't the domain the one place that is perfect for returning results, as in, no side effects? Don't understand the argument about getting the account in an invalid state. Both with exceptions as with results, they both abort the modification on the model.
@RichardJohn86
@RichardJohn86 4 ай бұрын
Looking healthy btw congratulations
@Codewrinkles
@Codewrinkles 4 ай бұрын
Thanks. Doing a lot of sport the past 9 months :)
@XXnickles
@XXnickles 4 ай бұрын
I disagree partially in the point of not throwing when validating. In my opinion, exceptions should be triggered only on IO related operation in both edges (input and outputs) and your domain should be strong avoiding primitive obsession (aka, domain types should never allow wrong representation of their values...which might mean they actually throw expection as well) The problem here is we don't have a way in current C# and idiomatic way to model "issues" and exception are the actual accepted basically the "accepted" way to deal with them. It is a hard and "controversial" problem, but in the end the best guide is you do whatever you consider more appropriate for your case and your team
@Ellenki_007
@Ellenki_007 3 ай бұрын
I don't like Russian accent but explanation is good.
@Codewrinkles
@Codewrinkles 3 ай бұрын
I'll work on improving my accent. Thanks for the feedback!
@KREKER8331
@KREKER8331 4 ай бұрын
Great Video. Thank`s a lot.
"Don't Throw Exceptions, Use A Result Pattern" is BAD ADVICE!
19:22
Codewrinkles
Рет қаралды 3,8 М.
Testing Minimal APIs Made Easy
1:00
Codewrinkles
Рет қаралды 1,5 М.
Гениальное изобретение из обычного стаканчика!
00:31
Лютая физика | Олимпиадная физика
Рет қаралды 4,8 МЛН
Арыстанның айқасы, Тәуіржанның шайқасы!
25:51
QosLike / ҚосЛайк / Косылайық
Рет қаралды 700 М.
The evil clown plays a prank on the angel
00:39
超人夫妇
Рет қаралды 53 МЛН
That's NOT How Async And Await Works in .NET!
12:25
Codewrinkles
Рет қаралды 29 М.
Why I Prefer Exceptions To Errors
1:05:31
ThePrimeTime
Рет қаралды 202 М.
C++ Super Optimization: 1000X Faster
15:33
Dave's Garage
Рет қаралды 334 М.
Getting Started with .NET Aspire and SQL The Right Way
24:04
Codewrinkles
Рет қаралды 3,5 М.
Rant: Entity systems and the Rust borrow checker ... or something.
1:01:51
When To Validate and When To Throw Exceptions?
11:00
Ardalis
Рет қаралды 10 М.
5 deadly Rust anti-patterns to avoid
13:25
Let's Get Rusty
Рет қаралды 40 М.
The Only Unbreakable Law
53:25
Molly Rocket
Рет қаралды 359 М.
The Return of Procedural Programming - Richard Feldman
52:53
ChariotSolutions
Рет қаралды 64 М.
Гениальное изобретение из обычного стаканчика!
00:31
Лютая физика | Олимпиадная физика
Рет қаралды 4,8 МЛН