Exceptions are evil. This is what I do instead.

Sdílet
Vložit
  • čas přidán 10. 05. 2024
  • In today's video we'll talk about why exceptions are evil and why you should probably stop throwing exceptions for flow control.
    Not throwing exceptions will make your code faster, simpler, faster to debug, and easier to maintain.
    We'll also see the alternative flow control approach which is the result pattern. The result pattern will be demonstrated using ErrorOr, and we'll see how the ErrorOr library can be used to elegantly return errors instead of throwing exceptions.
    ErrorOr: github.com/amantinband/error-or
    Connect with me on 'em socials:
    Twitter: / amantinband
    LinkedIn: / amantinband
    GitHub: github.com/amantinband
    Check out all my courses on DomeTrain: dometrain.com/author/amichai-...
    Support the channel and get the source code: / amantinband
    Thanks for watching, don't forget to like & comment & subscribe! ❤️ 💻
    00:00. Intro
    01:17. Exceptions suck #1 - Messy
    03:45. Exceptions suck #2 - Complex
    08:40. Exceptions suck #3 - Heavy
    09:46. Exceptions suck #4 - Privacy
    14:12. Exceptions suck #5 - Monitoring
    17:19. The Result Pattern
    17:58. ErrorOr
    20:15. Result Pattern ftw #1
    21:42. Result Pattern ftw #2
    23:39. ErrorOr 2.0
    24:17. Outro
  • Věda a technologie

Komentáře • 90

  • @99aabbccddeeff
    @99aabbccddeeff Před měsícem +33

    Sometimes exceptions are good, it doesn't turn code into if-hell after every method call. But they are for exception situations and the main problem is not exceptions, it's how people use them.

    • @PaulPetersVids
      @PaulPetersVids Před měsícem +4

      I'd argue that it's either if-hell or try catch block hell. You'll have to do one or the other. I find reading if blocks much easier to read than wrapping my head around the unpredictable control flow of try catches where control can teleport the program at any step.

    • @99aabbccddeeff
      @99aabbccddeeff Před měsícem +12

      ​@@PaulPetersVids not really. If you write try catches like if-hell, you are doing something really wrong and you should follow another approach like, for example, in the video. Exceptions are needed, as I said, for exception situations. It doesn't mean you should write try catches everywhere in your program, it means that try catches will be in some places where they are needed. And when you make chain of calls (Method1 -> Method2 -> Method3 -> ...) you don't need to write "if" in all those methods to check if an error was occurred. You just catch the exception in one single place.

    • @parlor3115
      @parlor3115 Před měsícem +1

      @@99aabbccddeeff Not going over application design, using this pattern makes for shorter code. For example, if you're returning either of two results, then it's a single if check with a return statement, where, using exceptions, will always result in at least a full try catch block. Also, I side with Paul about "if" statements being more readable.

    • @PaulPetersVids
      @PaulPetersVids Před měsícem

      @@99aabbccddeeff Yes, exceptions are necessary in C#. Almost all I/O calls can throw exceptions due to reasons outside the program. If you aim for a robust program, you should handle these exceptions instead of simply swallowing them. If you choose not to swallow them, you have two options: either throw an exception, which would require another try-catch block above the method calling an I/O method, or use a result type with an if statement. The if statement is much smaller and easier to follow than a try-catch block above the throwing method.

    • @PaulPetersVids
      @PaulPetersVids Před měsícem +5

      ​@@99aabbccddeeff Yes, exceptions are necessary in C#. Almost all I/O calls can throw exceptions due to reasons outside the program. If you aim for a robust program, you should handle these exceptions instead of simply swallowing them. If you choose not to swallow them, you have two options:
      1) either throw an exception, which would require another try-catch block above the method calling an I/O method
      2) or use some form of a result type (option, success/error thing) with an if statement above the method
      3) maybe pattern matching with some/none as well (I know I said two lol)
      Either way, whatever you choose is better than the insane try catching I see in many languages that use try catch for error handling.

  • @nirajjoshi9147
    @nirajjoshi9147 Před měsícem +7

    You are absolutely right.
    If you ask me, I use exceptions in exceptional cases only.😊

  • @B.3.N
    @B.3.N Před měsícem +17

    In theory it's the same procedure as in Go but slightly worse. For me it's the complete opposite of what you say. It a.) becomes a burden, because you have to explicitly do error handling on every caller. b.) because of that it's getting really fast really messy and last but not least c.) I have to pollute my code with (in this case) an external dependency. Throwing domain specific exceptions, catching them separate if necessary or globally is in my opinion a cleaner way - but I guess this is subjective. For me another benefit of throwing domain specific exceptions is, that you know already by the name of the exception where the underlying problem most probably occurred.

    • @amantinband
      @amantinband  Před měsícem +8

      Those are valid points. I think it also depends heavily on the project and the team.
      Personally, I prefer the mess I can predict than the mess I cannot.
      In every single large application I worked on within Microsoft the error flow was complex. When I say complex, I mean entire OneNote pages per error scenario to understand the flow.
      The reason is - when an exception is thrown, god knows where you're going next.
      Is the catch clause catching the exception type? no, but if it catches the parent type so it enters the clause.
      Did the dev forget to put a log message in one of the catch clauses? Great, even harder to understand the execution path.

    • @B.3.N
      @B.3.N Před měsícem +6

      ​@@amantinband Thank you for taking the time to respond. I like your take with the mess. :) In the end, it really depends on yourself and the team working on the project and it's therefor often a subjective team decision that has to be taken

    • @franciscorusso8062
      @franciscorusso8062 Před měsícem +4

      At the end of the day, the Result pattern is a monad, and in this library, the Bind method is implemented with the Then method. By using Them method, you do not have to explicitly handle errors on every caller. You can use Then to run your logic when it succeeds, return the error if not (like bubbling up the exception), or handle the error if you like.
      The problem I see (and is very true in go) is when you're doing imperative programming you're forced to always handle the error.

    • @moellerdk93
      @moellerdk93 Před měsícem

      most probably occurred...

    • @TazG2000
      @TazG2000 Před 24 dny +1

      @@amantinband I think I get where you are coming from, because I have experienced teams that have created messes because they follow bad practices, where the response was to constrain them to using some specific convention as an attempt to "force" them to design better code. But in opinion, this never works in the end. If they don't understand how the new convention helps them, they will find a way to abuse it and create messes as bad or worse than before. There is no substitute for people actually *understanding* what they are doing and why.

  • @StevenHartgers
    @StevenHartgers Před měsícem +10

    Should have named the library ErrOr, as "orOr" is redundant - although it would be impossible to distinguish it while searching for "error" in a search engine.

  • @Eirenarch
    @Eirenarch Před měsícem +4

    I tried ErrorOr in one small part of my project. I had the following problems
    1. To make the controller code short I needed a relatively complex generic extension method to convert the ErrorOr to the ActionResult. This is OK if you use it everywhere but it was annoying when I tried to use it in a single controller experimentally
    2. I needed more results than Error or result and also inline way to define errors.
    Basically I want union types that can be declared inline like string | int but also named if need be.
    BTW when I use exceptions if I need to catch them anywhere but in the global handler I immediately switch to some form of results even if it is the most primitive.

  • @johalternate
    @johalternate Před měsícem +3

    There is a lot of divide on this topic and I love it. That said, the main reason why I like this approach is because I like the separation between Business Logic Expected Errors and Exceptions.

  • @moacir8663
    @moacir8663 Před měsícem +5

    At the first section of the video you mention that many exceptions may bring a mess in our project, but at the 22:50 creating a folder with other business exceptions classes don't take us to the same problem?

  • @antonmartyniuk
    @antonmartyniuk Před měsícem +5

    This is also my favourite Result pattern library. I was using OneOf before and I was slightly disappointed with it because of Matching and need to create empty classes for errors that didn't have any details.
    I first have seen this library in your DDD course, I guess. And I liked it more then any other library.
    Looking forward to seeing a error-or 2.0 video

    • @amantinband
      @amantinband  Před měsícem +2

      Very similar to what happened to me.. I really liked OneOf but was missing various practical features

  • @mazenamria5625
    @mazenamria5625 Před měsícem +4

    The way you've described the global handling in #2 (3:45) makes it look like it's hard to think of the control flow when using exceptions. However, it's not a global handling logic that sometimes the component would propagate the exception to and sometimes won't. It's an extra layer on the surface of your application stack. Each layer/component would throw an exception that's understandable by the upper layer, and each layer has the choice to propagate that exception, convert it, or swallow it. The global error handling is always done at the top layer. And unless you're intercepting the exception on its way propagating to that global error handling it won't be affected.

    • @amantinband
      @amantinband  Před měsícem

      100%, I say this a bit later but maybe I wasn’t clear enough

    • @pagorbunov
      @pagorbunov Před měsícem

      But each layer should know nothing about upper layer, no?

    • @mazenamria5625
      @mazenamria5625 Před měsícem +1

      ​@@pagorbunov you can think of the exception as part of the contract between layers, the interface defines the explicit contract which is the methods and their usage, and exceptions are part of the implicit contract between both. According to DIP I think that the upper layer (client) should expose a contract of what it's expecting. Then, the lower layer should implement that contract.
      Explicit contracts are enforced by the type system while implicit contracts aren't. So it doesn't sound right to have an implicit contract, but even with Result objects you still doesn't know what errors should you expect and when. Unit testing might be an option to verify those implicit contracts.
      I like how in Java you can add `throws SomeException` as part of the signature and it'd then force the caller method to either intercept the exception or declare that it might throw the same exception as well.

    • @pagorbunov
      @pagorbunov Před měsícem

      @@mazenamria5625 got your points but those are definitely not my cup of tea

  • @jarogor
    @jarogor Před měsícem +2

    what kind of drawing tool is this?

  • @rubberuk
    @rubberuk Před měsícem

    Yes, convinced :) Excited for the follow up video.

  • @hoangsangnguyen2541
    @hoangsangnguyen2541 Před měsícem +1

    Thank you so much, Amichai. I love ErrorOr and am eagerly awaiting the next video about ErrorOr introduction. See you then!

  • @hamitkarahan2973
    @hamitkarahan2973 Před měsícem +1

    This video is even more exciting than Game of Thrones episodes. I dont know how happened but he convinced me😅Waiting for the next episode. Thanks!

  • @zikkrype
    @zikkrype Před měsícem

    Does ErrorOr support explicit/implicit operator overload?

  • @margosdesarian
    @margosdesarian Před měsícem

    What are your opinions on how Steve's Result package compares to yours?

  • @mohammadamini1036
    @mohammadamini1036 Před měsícem

    What about errors that happen in domain events handler that returns nothing? Or my domain model cunstructors?

  • @ciprianhoreanu714
    @ciprianhoreanu714 Před měsícem +1

    I am already using your ErrorOr library ever since I learned about it from the DDD series, and I like it a lot, with two exceptions: 1. sometimes, it can feel overwhelming to have to introduce "if checks-error returns" after every method call 2. I think it would have been nice if you explained in the video how do you handle stack traces when using discriminated union-like constructs, because sometimes, when looking in logs, a stack trace is really helpful, when the flow path that led to the exception is complex and long

  • @diegocataldi8335
    @diegocataldi8335 Před 4 dny

    Hello, I'm very interested in purchasing your DomeTrain courses on Clean Architecture, but since I'm not 100% familiar with English, I need to know if they are all on CZcams or if the platform has automatic translation to Portuguese (Brazil).
    Congratulations and I look forward to your response for purchase!

  • @shafialanower3820
    @shafialanower3820 Před 7 dny

    Is there a particular reason you use vs code to demonstrate these topics? Started seeing decent amount using vs code to demonstrate c# concepts instead of vs

  • @Stoney_Eagle
    @Stoney_Eagle Před měsícem

    I'm a beginner with C# and I have been doing this manually for every endpoint in my project😅, I'm gonna give your library a try!

  • @num1nex337
    @num1nex337 Před měsícem +1

    Im definitely a fan of errors as value, but on the other hand in a language where exceptions are first class citizenship I'd rather not try to go against the design of a language. Great video tho and package aswell!

  • @behh89
    @behh89 Před 29 dny

    Coming from a Golang Background, the exception treatment was one of the most confusing topics to me in C#.
    I really like this approach of returning the result and/or error on each function.
    This helps to develop easy to read code and not worry so much about things that come from nowhere, I think it makes easier to create better unit tests too.

  • @obiwanjacobi
    @obiwanjacobi Před měsícem

    I think the Result pattern (ErrorOr) only works if there is some language support to propagate errors for instance. In real world cases the Result.IsSuccessful check (or variations thereof) gets old really quickly and bloats your code immensely especially when more methods are being called that each have to be checked.
    Also keeping track of stuff you may have to dispose when you early exit on an error is error prone. There also some language support could help out. Some languages have a `defer` that can schedule a method call for later when the scope is exited.

  • @margosdesarian
    @margosdesarian Před měsícem +2

    I have always designed my systems to catch actual exceptions directly where they occur and send "result" type classes back to the consumer, that have a meaningful message and/or enum (or a class or record) that can be used for program flow. That includes apis - why would you send a Http NotFound "error" back to the consumer when its actually a logic situation? They might think there is a network error, or that they had specified an incorrect api address or something.

    • @duongphuhiep
      @duongphuhiep Před měsícem

      It is a convention that a Restful API returns 404 when the requesting "resources" is not found. Mistyping the adresse or the id of the resources fall into this category.. The different is that Your Cloud provider might return a 404 with a Html body, but your application might return a 404 with a Json body. Note: I understand the reason of 404, but I dislike it Restful API in general

    • @cristinelcostachescu9585
      @cristinelcostachescu9585 Před měsícem

      HTTP 4xx codes are not errors, just the result of attempting to fetch the resource. An "error" (or rather, exception in this case) is when the network goes down and the TCP connection gets cut off.

  • @TazG2000
    @TazG2000 Před 25 dny +1

    The main problem presented is the fact that a global exception handler is responsible for handling all types of failure cases. This is bad, but I disagree that disallowing exceptions is the solution. Regardless, we need to move the responsibility where it belongs. Whichever component is aware of the failure case and decides the result of it, is the one that should actually be handling it (whether that is by catching exceptions or by checking a result object). I'm still concerned that the guidance here seems to be "exceptions are bad, never throw exceptions" when in reality different solutions are appropriate for different problems.
    Basically this is looking at two extreme cases: Errors that flow up the entire dependency tree to a global handler (which should be avoided unless they are truly unexpected), and ones that are handled directly by the calling component. However, there are plenty of cases in between. It makes sense to use the result pattern if we know that the caller will usually be responsible for handling failure states. But otherwise, what is the value in forcing callers to collect errors and pass them through the tree? All we are doing then is manually re-implementing what exceptions already give us for free, and polluting all the layers in between with details they should not be concerned with.
    On the point about privacy: This is also something that we need to handle regardless. At the end of the day, even if we refactor all of our own components to never deliberately throw exceptions, we will still have unhandled exceptions that need to be reported somehow, that we will want to be able to debug. I agree that the general solution here is that your public interface should only use error codes and descriptions that you control - but disagree that *replacing* exceptions with your own construct is the only way to do so. This information can be included with exceptions (either by using your own exception class, or some way of attaching metadata to existing exceptions). Then, the global handler should be designed to only output the public information publicly, but still be able to log the actual exceptions and/or display them when running in a development environment. This also allows us to freely throw our own unhandled exceptions for unexpected cases - that we will be able to debug if they do happen - without worrying about what the stack trace or inner exceptions might expose, because we know they are still never going to be displayed to the user anyway.

    • @amantinband
      @amantinband  Před 25 dny

      Exceptions (for flow control) are evil should be the take away

    • @TazG2000
      @TazG2000 Před 24 dny +1

      @@amantinband ​ That suggests that exceptions (not for flow control) are okay and should still be used. But what I'm seeing is that you're converting all instances of exceptions *to* a flow control construct, even if the original exception was not for flow control. So now we have this flow control pattern of "if (isError) return errors" for every unexpected result, requiring components in every layer to change their interface to ErrorOr and implement this flow control, even if they don't handle results themselves, just to allow unexpected results to bubble up - which is exactly what exceptions are for. Why are we adding flow control where it didn't exist before?
      In short, the result pattern makes sense when the result types are well-defined and the callers specifically know how to handle them. Otherwise, you're doing exceptions with extra steps.

  • @nikolaoschalkias5472
    @nikolaoschalkias5472 Před měsícem

    LIghtbulb went on. Will definitely try it out.

  • @HaimBell
    @HaimBell Před měsícem

    I use the result pattern; your solution is much cooler than mine

  • @DaminGamerMC
    @DaminGamerMC Před měsícem

    Programming in rust is where i learnt how amazing are Errors as values and the Result pattern and how much it helps.

    • @z0nx
      @z0nx Před měsícem +1

      And how terrible the support for this kind of thing is in c#. No decent discriminated unions, no shorthand (monad-like) syntax to deal with the verbosity of combining/handling errors.

  • @hatiko8227
    @hatiko8227 Před měsícem

    Why don't just return tuple like this (error, value)?

  • @egitim10
    @egitim10 Před měsícem

    I think, it is simpler, to write code and test with exception as less as possible. Than, to create custom exception for each layer, handle and log them in global exception. At the middle layers, use 'throw' keyword magic to keep stack trace. By doing that we can handle any exception message as you want and it is not complex at all. I am not a professional but I do this way and did not meet any issue until now...

  • @baranacikgoz
    @baranacikgoz Před měsícem

    For anybode who thinking you have to handle success or failure repeatedly in each endpoint, just create an endpoint filter that is logically same as global exception handler but for result objects deserialization to the response. I am using it, returning the result object directly from endpoint, then endpoint filter catches it with await next(), then takes care of with something like "return result.Match(......)" globally.

  • @cristinelcostachescu9585
    @cristinelcostachescu9585 Před měsícem +1

    Rule of thumb: exceptions are exceptions. You never catch your own exceptions, unless it's the very end of the road and you need to return a message to the user. You only catch exceptions from code that is not yours (libs, external services), decide what to do. Also, you never re-throw the same exception: if you caught it, it means your intention was to handle it - not to mess around with it.
    Exceptions should always be at most 2 levels up the response to the caller (user). 2nd level (furthest) is exceptions thrown by libraries or external services. 1st level (closest) is your own exceptions. At level 0 you just decide the message to return to send to the caller.
    The entire Errors/Exceptions folder, try-catch, return try throw catch ball mumbo-jumbo is nonsense. Exceptions were never meant to be a regular control flow pattern - it was meant to be an EXCEPTIONAL control flow, for situations where you literally exhausted any alternative control flow handling.
    In addition to the mentioned stack memory allocation for each exception thrown (or embedded), let's also not forget that some languages require manual heap release (C/C++), throwing an error may get you out soon and quick, but it could leave a memory leak behind (and you may not be in a place where you can free that memory after the Exception thrown).
    Again, only use exceptions for exceptional situations, not for regular control flow.

    • @isodoubIet
      @isodoubIet Před 29 dny

      "let's also not forget that some languages require manual heap release (C/C++), throwing an error may get you out soon and quick, but it could leave a memory leak behind"
      That's wrong. Destructors are called during stack unwinding.

  • @airixxxx
    @airixxxx Před měsícem

    I think the extension should be Result, having the error first gives me anxiety.

  • @ewilliams0305
    @ewilliams0305 Před měsícem

    I love the result pattern. One thing I struggle with is the result explosion. Sometimes it’s starts to feel like everything needs to return a result. I try to use it for a more complex parts of my application where things will certainly go wrong.

    • @gichwanene4281
      @gichwanene4281 Před 22 dny

      I have a similar dilemma. The result pattern is very confusing because sometimes, it just feels like all your methods/functions should return Results. In python, that would mean I would have to do a lot of rangling with the typing and pydantic libraries to get my type annotations and validations to work with my Result class.

  • @R0ckyRocket
    @R0ckyRocket Před měsícem

    האמת אחלה חבילה כל הכבוד!
    אני מאוד אוהב לעבוד עם language-ext
    בגלל שזה מוסיף לי גם option struct.
    לדעתי זה אחלה רעיון לסרטון דרך אגב.

  • @nove1398
    @nove1398 Před měsícem

    Great knowledge share here.

  • @tryandgain
    @tryandgain Před měsícem

    I believe exception has role to play, especially in case you want to write log or send error message. The question is when to throw and when not to?

  • @TazG2000
    @TazG2000 Před 25 dny +1

    Here's my prediction, 30 seconds in:: You experienced working in projects that were messy because of engineers conflating 3 different concepts:
    1. validation
    2. completion status
    3. exceptions
    My take: If you always use exceptions to implement the first two cases, then you're going to have a bad time. If you go all the way and refuse to use any exceptions even in the third case, because you decided they were "evil", you're also going to have a bad time.

  • @arleyhenostroza
    @arleyhenostroza Před měsícem +1

    I really like the result pattern, and I have tried to use it in C#, but the lack of language support, and the fact that is not the standard im C# world, make it hard to use it, if C# added languaje support like rust ? for easy return on erroe or improved pattern matching with auto cast to the succes type and exhaustive matching, I would always use it in C# for the expresive error flow and error handling, but with the current language limitations the ErrorOr library is very good, great work

  • @luigicfilho
    @luigicfilho Před měsícem

    Thanks for this, i was searching something like that, i was using the iactionresult in the services that are injected in the controllers, but was not ideal, this can solve my issue :)

  • @JuanOG
    @JuanOG Před měsícem +1

    I would say the Library should not expose the errors and value variables without the match function. That is what acts as a perfect discriminated union when it will handle the if condition. Letting the dev access to the variable can caused missed handling. With the match function you have to handle both cases.

  • @dasficus
    @dasficus Před měsícem

    i prefer Enums with multiples subdescription with helpers like partial Sealed Class to do the same ...

  • @screamiboy
    @screamiboy Před měsícem

    Isn’t that just using the tip of the iceberg of functional programming? So why not just use e.g. LanguageExt which uses the proper wording for functional programming and can be applied on much more usecases?

  • @botyironcastle
    @botyironcastle Před měsícem +2

    c# is not designed to use the result pattern, your dependencies won't use it, you get a mess. If you want the kinda monadic discriminated union approach instead of exceptions then go with GO or languages which are designed to that. I would be happy if java and c# wouldn't be the mess they are, because I hate GO but have to admit it's a better overall design.

  • @TomEugelink
    @TomEugelink Před měsícem +1

    "Exceptions for flow control are evil", on that we can agree, but on this video title we cannot 😊. My issue is that a movie being not found or hidden is not an error, it's not an exception, it's expected within the application. You simply have an Optional that can hold some information on why it does not contain a value.

    • @amantinband
      @amantinband  Před měsícem +1

      Haha yeah that’s the full answer. 100% agree on the not found and is what I practice as well: github.com/amantinband/clean-architecture

  • @MenelBOT
    @MenelBOT Před 28 dny

    Wow that sounds like a ton of your opinion with no backup

  • @fusedqyou
    @fusedqyou Před měsícem

    Firstly, exceptions being heavy doesn't matter. You should not have exceptions thrown in production code, and if this does happen you fix it. Exceptions do not exist as a "general" application feature so assuming it's supposed to be anything like that is bad.
    Secondly, privacy doesn't matter because of the first point. Exceptions should not be thrown. In the event an API throws an exception it has build in features to redact any sensitive information.
    The result pattern is great, but it can't replace exceptions. For some reason you think it can. The whole point is throwing an error that is delegated to the first instance catching it, effectively ending code that can't handle the result that would otherwise be given. If you have the result pattern, your code clearly knows how to handle the issue. If you implement it just to end the method with another Result, you are wasting your time doing something an exception could have done in a more readable way.
    Don't reinvent the wheel with something that doesn't work as well. These videos are just going to confuse developers into using something that works worse, and have them end up having to refactor it.

  • @ErikVolger
    @ErikVolger Před měsícem

    The next version could be called SuccessOr. Turning the concept upside down...

  • @GnomeEU
    @GnomeEU Před 29 dny

    Cluttering your project with generics is just as bad tho.
    Imagine one day you have to refactor all those generics, you have to touch every single method signature in your application.
    Maybe thousands of signatures.

  • @tc05698
    @tc05698 Před 29 dny

    I have to disagree with your take, I've seen systems with both approaches and have found that exceptions, when used correctly, reduce complexity of the overall system.
    1. Exceptions being consumed by the system should almost never be caught by calling components. Obeying this rule will resolve the majority (if not all) of the added complexity you discussed here. Sometimes you can't get around it due to consuming third party components, but I consider that an exceptional situation and the responsibility of wrapping/transforming a third-party component should be on the closest calling component.
    2. Exceptions are Heavy - They can be, but at the same time, you are gaining a better view into what happened and where. Which, unless your talking about a performance critical section of code, is worth the weight to not deal with the complexity of doing it yourself.
    3. Privacy - Usually the database already contains personally identifiable information, so logging it back into the database shouldn't make a difference to the security posture of the app. (And there are great classifiers for identifying that information and stripping it from the logs)
    4. Creation of "God" exception location in global handler - This doesn't need to occur if each exception type implements an Interface that calls out a conversion method to a shared object type that is used for return. This puts the onus of knowing how to convert each exception type to the corresponding response largely on the exception type itself, turning the God function into a simple translation/logging function.
    5. Monitoring - Alerting on errors occuring in the app are better left extracted to the monitoring software, why add the complexity of monitoring for high error rates to the app when it isn't needed and most services do it out-of -the-box.
    6. Result Pattern - This works, but puts the cognitive load on the developer calling the method to check result state, which they won't do at some point, and what do you get? An exception. Not to mention, littering the code with this special class on all paths that may or may not care about it, but now must care about it if only in it's usage for returning.
    In summary, I would use the Result Pattern if it was a performance critical situation (95% of the time it's not), but otherwise stick to the use of Exceptions when the expected unexpected occurs. I also think the need for the result pattern is often driven by the decisions made in the components themselves. In the case of the GetMovie function, it should be the responsibility of the caller to throw an exception if the movie doesn't exist, because it knows whether or not it matters. I would just have that method return null if the Movie doesn't exist and leave it to the preceding layers to determine if an exception should be thrown. Lastly, If you fail, you want to fail loudly. I feel like the Result pattern is failing quietly.

  • @PatricSjoeoe
    @PatricSjoeoe Před 10 dny

    I like exceptions, i think the main problem is that people use them wrong.

  • @gearboxworks
    @gearboxworks Před 29 dny

    Don't use exception handling for flow control? Golang enters the chat...

  • @Tony-dp1rl
    @Tony-dp1rl Před měsícem

    In the end, Exceptions should be ... Exceptions, not something you know Might happen and know how to handle correctly.

  • @lextr3110
    @lextr3110 Před 29 dny

    haha common exceptions are bubbling up what so complicated about this. Your arguments are only valid if somebody does not use exceptions like they should be used..

  • @pierrek007
    @pierrek007 Před 29 dny +2

    This is very bad advice. Your .NET code will throw exceptions anyway → you have to handle them anyway → you can just throw exceptions as well. And there is no need to have double approach for exceptions and errors which are quite the same thing.
    Exceptions are only for exceptional cases. Use results for standard cases, not exceptions. If "not found" is usual to your app, then you should have special result for that case. That's for sure.
    But I still recommend using exceptions for exceptions and use this library only in case - if you have troubles with performance. Exceptions are slow, that is true. If this is not issue for you simply use exceptions.
    And to address points of the video - 1: sure, if you are messy programmer, you will have messy exceptions 2: actually the same point, showing example of bad code and explaining that exceptions are bad? doesn't make sense... 3: true, I agree with that; but again, exceptions are for exceptional cases; 4. nonsense, if you are logging you are already considering what to log and who has access to the logs and this doesn't have anything to do with the concept of exceptions itself; 5. the same... you have monitoring issues and you are saying that is fault of exceptions? the same will happen to your errors, if you throw them to your monitoring. In many exaples of the video you do some bad design decisions and then you are saying that exceptions are the reason, which is not the case at all.

  • @vadimemelin2941
    @vadimemelin2941 Před měsícem +1

    Rust is good it rewrites other languages, huh

  • @catsgotmytongue
    @catsgotmytongue Před měsícem

    I started using an error as value approach over exceptions where possible a few years ago. It has been much better for forcing the calling code to handle the result instead of letting exceptions throw all around the code base. Its not at 100% in our code base but it is definitely a goal in making our control flow more predicable and understandable. It prevents a lot of additional headaches like determining the true root cause of an issue.

  • @linuxtutorialshindi8582

    VAVR in java.