Why I Prefer Exceptions To Errors

preview_player
Показать описание
Recorded live on twitch, GET IN

### Article

### My Stream

### Best Way To Support Me
Become a backend engineer. Its my favorite site

This is also the best way to support me is to support yourself becoming a better backend engineer.

MY MAIN YT CHANNEL: Has well edited engineering videos

Discord

Рекомендации по теме
Комментарии
Автор

Calculating fibonacci recursively is a common stand in for some moderately complex task that will reach very high stack depths. You could substitute in parsing XML tags, or any other tree data structure, and the point would stand. If you use errors as values, then your error checking code is included in-line with the rest of your code, which means an if check and a short jump. This means your hot path code is bigger and fits in lower level caches less well. Exceptions use a long jump table stored externally to the local hot code. So all of the exceptional path code is _not_ sitting in your local caches. This makes the non-exceptional case run significantly faster, at the cost of making exceptional code marginally slower.

When you throw an exception, that throw statement _is_ a long jump, to the global exception dispatcher, which takes the current program counter as an index into the exceptional path table to determine where to go next. The where-to-go-next will be the stack cleanup for each frame between the current continuation and wherever your first catch is. Again, this is out of band to your regular code, so will need to be loaded into the L1 cache when an exception happens.

yellingintothewind
Автор

This article would have been less upsetting if it was called "Why exceptions aren't as bad as you think"

allesarfint
Автор

From a Java perspective, my impression is that Prime is more against unchecked exceptions than checked exceptions.

JohnDoe-buqp
Автор

Don’t say you’re “handling the error” if all you’re doing is checking if an error exists, add a log msg, wrapping the error, and then returning that error up the chain. That’s literally what exception throwing is doing for you for free.

refusalspam
Автор

I prefer languages where I know what errors the function can have. If a function is updated with a different Exception, then the caller can't know this. Program will happily run, even if the Exception is not handled. But if the error type was coded into the function signature, then the caller only needs to know about this function and not the entire stack. And any change would make it incompatible, and force the caller to update to handle any error.

thingsiplay
Автор

Regarding performance, we have the following dichotomy: absence of error and presence of error.

- Exceptions are fast in the absence of error and slow in the presence of error.
- Error values are medium in the absence of error and medium in the presence of error.

Since the absence of error is expected to be (much) more common than the presence of error, exceptions are expected to have better performance.

If the absence and presence of error are similarly likely, using exceptions is an anti-pattern, which even has a name: "exceptions as control flow". In that case, you should use a return value, even in a language that supports exceptions.

BrankoDimitrijevic
Автор

Bro has never used rust web frameworks. They all return 500 code when a handler panics. Exactly as a top-level exception handler would. Effectively, unwrap is throw for most web frameworks in rust.

alexpyattaev
Автор

The argument about Java's OutOfMemoryError was completely wrong because Errors in Java are not even meant to be caught at all (google the difference between Errors and Exceptions in Java).

grzesiekaz
Автор

The comments and Prime both seem to have missed the key point in the handling section:

Thrown exceptions _force_ the error to include context by creating a stack trace etc. By having the language handle exceptions, you can enforce certain rules about your errors that you can't when errors are merely values and then you are at the mercy of the individual writer.

AnyVideo
Автор

Error handling in complex systems is highly contextual. You might not have use a single silver bullet that kills all problems at hand. For example when you write SC software with high performance requirements you tend to prefer return error by value, while errors in a UI exceptions are usually preferred.

davidlofstrand
Автор

the main trick to recover from OOM is to always have the memory pre allocated for handling the error, and/or(usually and) having some of your used memory being forced reclaimable, like if it was minecraft you could have pre-allocated memory for everything u need to drop chunks (sections of game world) from memory.

xFlRSTx
Автор

There is a time to use exceptions and a time to pass back errors. Neither time is 'never' nor 'always'.

Rick-mfgh
Автор

My biggest takeaway from this video is that Santa isn't real. What the heck guys

taestott
Автор

This whole conversation seems a bit heated and does not get down to the core. Exceptions and error values are the same thing IF you are talking about checked exceptions. Unchecked ones are what Prime has trauma with. I am working with some very performance sensitive code and I would NEVER use errors as values as it would literally half the performance. I think it is very reasonable to have a separate unhappy path when the unhappy case is a rare valid state or a coding error.

lapissea
Автор

My approach: exceptions are for exceptional cases, result type with errors - for expected failures like user input validation, not found, unauthorized, etc.

YT-drqi
Автор

If I'm correct, "std::expected" is slow because the copy constructor of the "std::string" is being invoked every time you construct the "std::unexpected". To reduce memory allocation, the author should've used the move constructor by using "std::move". Therefore, the latter implementation allocates string on the heap multiple times compared to the exception implementation.

Maybe the compiler is unable to optimise the allocation or the pattern because the "std::expected" is a new feature, but I think it'll improve in the future as more use cases are optimised.

amitsingh
Автор

Ok so where am I wrong here? Go for example forces the checks of error values basically everywhere. How is this different than try-catching EVERYWHERE? If you write the checks for exceptions as often as Go forces you to check for error values aren't you essentially in the exact same situation? You can handle the exceptions in the exact same way?? Right? So really Prime seems to just like that languages with errors as values FORCE the check throughout the code where with exceptions you have the choice of sending them up the call stack by not checking them?? Am I lost?

ShootingUtah
Автор

In rust you can recover from a panic. Most server libraries do this on every connection.

alienmsehunter
Автор

At the outset I’m struggling to see a real world difference if you’re managing exceptions properly… try catching everything is horrendous but if I had to do a check on every returned value is it much different?

Kane
Автор

Ahh... error handling, the bane of our existence.. should you return, throw, exit, pause the stack, report to the user, log the error, etc.? How much context to include? stack trace? specific variable states? And how much is all of that allowed to affect performance?

defeqel