4 ms·
> But, since good programs don’t panic, and neither do good programmers, it’s very rare that using unwrap or expect is actually the right thing to do. I respec
by _nalply 2y ago
> But, since good programs don’t panic, and neither do good programmers, it’s very rare that using unwrap or expect is actually the right thing to do.
I respectfully disagree.
The assert!() macro is a way to document invariants. It's a bug if a variant is violated. It shouldn't have happened, but if it happens, then there's nothing the user can do except reporting the crash.
The unwrap() and expect() method document the invariant that the None and Err() variants shouldn't occur.
It's fail fast.
You should use error handling only if users would be able to handle the errors.
Tell the end user that the file they wanted to open is not readable, for example. Tell the users of your library that an error happened, like a parse error of a config file. And so on. Tell the users what they can fix themselves.
A bug in your library or program, that's something different. Fail fast! And Rust panics are perfect for that.
- zarathustreal 2y agoI think you’re misunderstanding the “fail fast!” advice. You want to fail fast in development not in production. In production you want maximum robustness. Users would rather see an error saying “whoopsie, maybe try that again later” than for the program to exit. That’s part of the reason why the functional error handling patterns are becoming so popular these days. They force you to handle errors and give you type-level info about how the program can fail.
- edflsafoiewq 2y agoYou can catch panics.
- echelon 2y agoPanics are unexpected and not the preferred mechanism of error handling. Stick to Result<T,E>.
- edflsafoiewq 2y agoThe GP said > Users would rather see an error saying “whoopsie, maybe try that again later” than for the program to exit To achieve this, you need to catch panics. Rust does not use Result for things the OP is talking about like asserts.
- nicce 2y agoIf you want to handle the assert cases, you should not use the asserts in the first place.
- edflsafoiewq 2y agoThat isn't possible. The assert may not even be produced in code you control. The reason panics/exceptions exist is it is too onerous to handle every possible error condition at all callsites (allocation failure and broken pipes are the famous examples), and it is not possible to enumerate all possible error conditions (unintentional programmer errors for example). People have religious ideas about handling panics for some reason.
- echelon 2y agoPanics shouldn't exist in modern Rust (if there is such a thing) at all.
- edflsafoiewq 2y agoI take it you mean panics should always abort?
- aw1621107 2y agoI'm not sure that is something you can rely in general due to panic = abort, though to be fair that's more a concern for library developers since IIRC they don't control that particular setting.
- Buttons840 2y agoI want my programs to fail fast in production too, because it makes it less likely that even bigger problems will arise. There are many problems that are much worse than a program crashing.
- IshKebab 2y agoIt depends on the program. You don't want your whole web server to crash because of a small error in one route. You probably don't want your CAD program to instantly crash and dump an error to the console because of a divide by zero in the constraints solver. Though in some cases like that I think it might be appropriate to use `catch_unwind()`.
- ryandrake 2y agoIf you're writing something safety critical like avionics flight control software, you probably don't want to crash in production either. I've also always interpreted "fail fast" as "Make defects obvious during development so they don't exist when you deploy to customers."
- Buttons840 2y agoThese are thought provoking counter examples. So, on a micro-level, let's say I have a function that expects x to be a float between 0 and 1, and there's some math and logic built on this assumption. Of course, in development if this expectation is violated, we fail fast and loudly and then fix the problem. In production it's not quite so clear. But still, is it ever the right thing to ignore that an invariant is violated and just hope that things somehow work out? > Make defects obvious during development so they don't exist when you deploy to customers. I agree with this phrasing. From another viewpoint, I would say: If your code checks an invariant, and that invariant is broken never (never!, not even in production) just continue on and hope that things will work out.
- IshKebab 2y ago> But still, is it ever the right thing to ignore that an invariant is violated and just hope that things somehow work out? Yes! Of course! In many situations it probably doesn't matter that the numbers go a little wrong, and that result will be better than crashing. In other situations it will be better to crash than to give junk results. As we already said, it depends on the situation.
- deleted 2y ago[deleted]
- joshka 2y agoThe easiest counterpoint to this is to think about a HTTP request. If your library is called by one route, and is known to fail in certain circumstances, this failure should not bring down the entire system. A well designed library should generally not make the choice to crash a system - that's the caller's decision. Yes there are exceptions to this, which is why TFA stated this as "rare" not "never". Using the assert macro in your code is (in my experience) generally bad. If your code is written well, you can never test that code path. Document invariants with tests instead, or better yet with infallible code.