STOP throwing Exceptions! Start being Explicit

STOP throwing Exceptions! Start being Explicit

CodeOpinion

3 года назад

25,447 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

@ashishsapkota945
@ashishsapkota945 - 13.11.2023 14:52

what if TLeft is void?

Ответить
@J-Kimble
@J-Kimble - 20.10.2023 00:29

Even though I love sum types, c# was not meant to be used with them. Nothing will make your colleagues and people inheriting your code-base resent you more than using arcane/opinionated coding patterns instead of industry conventions.
Don't get me wrong, I love Result<T, err> and Option<T> in rust or F# or zig, or o'caml but c# was not geared for it as of yet.

Ответить
@GnomeEU
@GnomeEU - 10.10.2023 06:27

You can decorate the methods with throws...description

Ответить
@user-ey2ei4oz3m
@user-ey2ei4oz3m - 08.10.2023 17:44

I think I would be more in favor of this approach if the compiler could guarantee that a method with an explicit type didn't throw an exception. The problem here is 3rd party code can still throw and you need to handle it. This approach is more explicit, but it's going to be jarring to developers that are used to exceptions.

Ответить
@SharonGavrielov
@SharonGavrielov - 03.10.2023 22:40

Too complicated and unclear usage. It looks like you are trying to write fancy, instead of simple an effficiant.
The sultation should be in the function documentation.

Ответить
@laughingvampire7555
@laughingvampire7555 - 28.06.2023 23:53

associating this with "honesty" is intellectually dishonest

Ответить
@Pekz00r
@Pekz00r - 02.06.2023 12:24

Great video! But I would probably name the properties of Either to something else. For example: "ok" and "fail" to make it even more explicit.

Ответить
@SashaPshenychniy
@SashaPshenychniy - 23.02.2023 01:13

How would you scale the idea to 5, 10, 100 possible error scenarios? Having Either<int, Exception> isn't any better than just int. 10 layers of nested generics is a nightmare... Creating generic variants of Either<> with every possible errors count? Still look scary...

Ответить
@twiksify
@twiksify - 28.01.2023 08:50

You can also add operator overloads for implicit casting which will remove quite a bit of boilerplate code when returning Either.

Ответить
@Yorgarazgreece
@Yorgarazgreece - 24.12.2022 17:05

Very good idea. Especially helpful at the service layer. However, I'd still use exceptions below the service layer as exceptions will always halt operation and don't need special handling/redirect at the parent level.

Ответить
@cicerofoscarini8890
@cicerofoscarini8890 - 01.12.2022 16:28

Hi! Thank you for the video. I really enjoy checking different ways to code. But using this approach wouldn´t add more if checking on your code? On your method AddItemToBasket, the line 29, UpdateAsync would be called even no item was added to Basket. In this case would case no harm, I guess, but in other case it could... So, would it add many more guard clauses? Could you clarity this, please? Thank you very much!

Ответить
@marcmigge
@marcmigge - 11.11.2022 20:46

Nice video. More people should use this approach to error handling. Although, the convention in functional languages like Haskell is to use left for the error and use right for the "right" value.

Ответить
@RobertoGimenez
@RobertoGimenez - 06.10.2022 21:43

You're recreating Rust's Result type, and match system.

Ответить
@zavjalovp
@zavjalovp - 19.09.2022 22:39

I don't enjoy this video :) I think you're clogging up your code on this... It looks like old "ContinueWith" problem. How can I know what is the Either "pattern"? I have to read documentation. How can I know about exception? I have to read documentation. How can I say about exceptions to my customer? Just write "exception tag" in "xml-summary"...

Ответить
@xaviersubira5154
@xaviersubira5154 - 06.09.2022 00:27

That's useful when you know how many exceptions can be raised (specially when they are not so much), and also when your program flow doesn't pass-through library dependencies.
But, how to deal with their exceptions?
Evenmore, what to do when your exceptions are handled externaly, such logging them
This sample shows a gentle manner of dealing with a 2-cases result, but that's a kind of panacea.

Ответить
@jon1867
@jon1867 - 05.09.2022 22:04

I don't know C# very well, but this approach seems pretty Rusty!
I've been thinking about doing something like this in typescript.
:)

Ответить
@pedroferreira9234
@pedroferreira9234 - 05.09.2022 01:19

OverEngineer imo. Just throw exception and have a globalexception middleware to take care of it.

Ответить
@s0psAA
@s0psAA - 03.09.2022 09:08

How would you handle exceptions thrown in constructor? Can't return either from constructor, but we could use NullObjectPattern maybe or something similar in a sense, that hold the validationresult or just an exception, if there is just one?

Make a new class than inherits from the one we want to create and return an instance of that instead?

Ответить
@JonathanYee
@JonathanYee - 30.08.2022 01:46

Something I've learnt from golang. Errors as first class. Most methods explicitly tell you if you have a returned result or an error. Exceptions are exception to what you believe your code does.

Ответить
@ziaulhasanhamim3931
@ziaulhasanhamim3931 - 14.08.2022 16:57

Exception should only be used when something horribly gone wrong and application have to terminate. The biggest problem it breaks the flow of code. For me the definition of function/method is a processing mechanism that takes in input and returns processed output. Exceptions really break that definition. Exceptions really make methods unpredictable. You can't say how will the method call behave if the method throws because it will break the whole code flow. And who can forget the issues of exceptions with async/task. Async with exception is a nightmare for beginner programmers you dont await or do continuewith exception gets ignored, sometime stack trace get messy and hard to understand whereas simple input-output behaviour of methods makes concurrency a piece of cake. And who can forget the performance issues. Exceptions can decrease the the performance drastically(I mean horribly).

Exceptions are really anti pattern for modern scale apps. If that's not the case why didn't modern languages didn't adopt exceptions?

Ответить
@sethdodson5475
@sethdodson5475 - 27.07.2022 15:55

I have some advice for you: please look up why C# does not have checked exceptions.

Ответить
@chrisvouga8832
@chrisvouga8832 - 19.07.2022 00:14

Am I the only one who hates the name of the Either type? I prefer the name Result instead

Ответить
@chrisvouga8832
@chrisvouga8832 - 19.07.2022 00:13

Another way to fix it is to not represent quantity as an int but instead as a custom Quantity type and make the impossible state like quantity < 1 impossible to compile. Not sure how painful the would be in c# but that’s how I would fix that particular issue in typescript.

Ответить
@rianby64
@rianby64 - 06.07.2022 14:41

Nice video! in golang we've "return &Entity, error" way to return either the expected result, either the error. Looks similar to me to golang way to talk ))))

Ответить
@danielschmitt5750
@danielschmitt5750 - 29.06.2022 15:32

Can you explain how you would deal with multiple either types in a mehtod? I can imagine this getting ugly quick.

Ответить
@Sousleek
@Sousleek - 17.06.2022 14:12

You successfully injected exception in function signature. So you showing it clear that it might happen. What to do if underlying function has 25 different exceptions? They're all can happen.
are you inclure in signature their common base class effectively hiding them back again?

Ответить
@MrBlackWolfX
@MrBlackWolfX - 07.02.2022 22:28

Both Either and Maybe functional structures are amazing ways of doing a more explicit code flow. Excellent tip!

Ответить
@brandonpearman9218
@brandonpearman9218 - 06.02.2022 11:11

I like the idea of explicit contracts. Bertrand Meyer's design by contract was a good idea, and we could do similar things today to improve our contracts but it was ultimately rendered useless by unit tests, think of your unit tests as your contract (packages maybe a different story, but honestly it's your own fault if you blindly trust a package). The benefit of throwing an exception is that it forces the application to stop and forces the client to deal with it. As opposed to continuing to function and accidently returning success statuses because the client didnt handle it. Those can be so horrible to debug.

Ответить
@rtl6832
@rtl6832 - 19.01.2022 07:05

Eh.. this seems like a bad idea to me..

Ответить
@dimitricharles9784
@dimitricharles9784 - 17.01.2022 12:22

Great video, I have done the same thing in a project in Java.

Ответить
@gds03_
@gds03_ - 21.12.2021 18:17

nice approach. Thanks! :D

Ответить
@AvineshwarSingh_APS
@AvineshwarSingh_APS - 22.10.2021 09:12

Nice. Something I do. Something I want to do better. Now, are exceptions so bad that we can't even digest or handle them and return some failure response by implementing some level of indirection?. Wanted to know your overarching thoughts.

Ответить
@Rene-tu3fc
@Rene-tu3fc - 08.10.2021 14:49

I don't like mixing functional-style with OO style error handling. Being explicit could just mean documenting that addItem can throw an exception.

Ответить
@kinggrizzly13
@kinggrizzly13 - 19.09.2021 02:04

I like this! Thanks for sharing.

Ответить
@InshuMussu
@InshuMussu - 03.09.2021 01:03

But exceptions can be handled globally.. where we can apply logging.. here I don't see the logging implementation

Ответить
@InshuMussu
@InshuMussu - 03.09.2021 00:59

It looks good, and it can be used somewhere in projects..

Ответить
@nhanang7289
@nhanang7289 - 17.08.2021 13:02

It looks like how golang handle errors and many people blame golang because of it :))

Ответить
@Greenthum6
@Greenthum6 - 09.08.2021 13:05

In this case the throwing method returns the quantity. It would be possible to just return 0 if quantity is less than 1. Exceptions provide a way to break execution during development which is invalidated with this implementation. Exceptions are meant to be thrown where they happen so I would use a dedicated error class instead. Returning multiple values is of course a good idea.

Ответить
@axonedge6459
@axonedge6459 - 08.08.2021 10:08

What happens if you have multiple errors? It's either inside either?

Ответить
@anrodse
@anrodse - 02.08.2021 00:21

why don't you just return a result object?
IResult<T> {
String Status {get;}
bool HasError {get;}
String ErrorMessage{get;}
T ResolutObject{get;}
}

Ответить
@hexdump8590
@hexdump8590 - 30.07.2021 11:50

I ussually have methods that throw more than one type of exception. How do you handle these scenarios?

Ответить
@zapdelivery5169
@zapdelivery5169 - 12.07.2021 15:40

We have enjoyed this in nodejs for over a decade. Leave the throwing and error handling to high level consumers. We create the errors internally but never throw them. Nodejs is known for the (err, result) callback pattern which is very similar to your Either Type implementation here.

Ответить
@Techiesse
@Techiesse - 07.06.2021 18:02

From Haskell?

Ответить
@kormuss
@kormuss - 22.03.2021 23:15

A tool to have for sure. But I would go with a combination of exceptions and results. In general there are many situations when you can't handle an exceptional situation which usually results in 500, logs, some general exception handler logic, etc... and thats fine. No need for additional abstractions, or complexity (if implemented poorly).

Ответить
@matiascasag
@matiascasag - 03.03.2021 01:59

Nice video. Also "Either" can be a struct and with that avoid null reference exception, and you can use implicit operators to directly return the TLeft or TRight without having to make a new Either object from the AddItem method, like this:

public struct Either<TLeft, TRight>
{
private readonly TLeft _left;
private readonly TRight _right;
private readonly bool _isLeft;

private Either(TLeft left, TRight right, bool isLeft)
{
_left = left;
_right = right;
_isLeft = isLeft;
}

private Either(TLeft left) : this(left, default, true)
{
}

private Either(TRight right) : this(default, right, false)
{
}

public static implicit operator Either<TLeft, TRight>(TLeft left)
{
return new Either<TLeft, TRight>(left);
}

public static implicit operator Either<TLeft, TRight>(TRight right)
{
return new Either<TLeft, TRight>(right);
}

public T Match<T>(Func<TLeft, T> left, Func<TRight, T> right)
{
return _isLeft ? left(_left) : right(_right);
}
}


* Then you can "return new InvalidOperationException()" or "return existingItem.Quantity"

Ответить