5 ms·
> Panic isn't supposed to be "I'm not sure what to do now, maybe my caller will know?". So panic is supposed to be “I’m not sure what to do now, I don’t care i
by zoky 3y ago
> Panic isn't supposed to be "I'm not sure what to do now, maybe my caller will know?".
So panic is supposed to be “I’m not sure what to do now, I don’t care if my caller knows”?
No process running outside of kernel space ever has any business panicking. Throw an error and move on with your life (or don’t, that’s fine too) but don’t punish your caller by forcing it to crash because you failed to foresee X, Y, or Z circumstances.
- xyzzy_plugh 3y agoIf it's reasonable for the caller to continue then return an error. If the state of the world is irreconcilable, panic is the right call.
- zoky 3y agoAnd how is the called method supposed to be able to determine whether the state of the world is irreconcilable? For that matter, how is the called method supposed to determine what the state of the world even is? And why on Earth would we trust it to do so? Is encapsulation not even a thing anymore? I really just don’t understand.
- bogeholm 3y agoA classic example is: - Accessing array out of bounds: panic - File not found: error
- nishs 3y agoThere are two "kinds" of panics: those initiated by the Go runtime, and those initiated by the program author, though technically there isn't a distinction. When you access an array out of bounds, the Go runtime initiates the panic. On the other hand, for a condition that the program should hold but doesn't, the program author should initiate the panic. For example, in the exhaustive switch below, reaching the default case means that either you have somehow incorrectly allowed the construction of an invalid token value earlier in your program, or you have missed to account for a valid token value in this function. func (t token) symbol() byte { switch t { case add: return '+' case sub: return '-' case mul: return '*' case quo: return '/' default: panic("unknown token") } } Errors are different. For example, url.Parse returns an error if its input string is an invalidly formatted URL. package url func Parse(rawURL string) (*URL, error)
- zoky 3y agoThat is a terrible example of a reason to panic. If the programmer believes the list to be exhaustive and it isn’t, then the programmer is wrong. So raise an exception and let the caller decide what to do with it. But don’t punish the caller by forcing it to crash just because you made a mistake as a programmer.
- nishs 3y ago(in go, "raise an exception" means "return an error.") error values are meant to represent expected, unsuccessful conditions—internal properties of the program—during the program's execution. for example, looking up the address for a domain name is an operation that can be expected to fail at times, and an error is appropriate here. errors in go are not meant to represent properties external to the program, such as mistakes by the package author or documented incorrect usage of the package by the package user. in go these are panics. perhaps other languages use exceptions for both but that conflates.
- galangalalgol 3y agoThat is a great example of a reason to panic. There is nothing you can do at that point but return an error or panic, and something has really gone wrong if you are pulling bad tokens out of a hashmap you made yourself, tonthe point I think you should panic. Sadly, almost all the panics I see coming out of rust crates are because someone called unwrap instead of handling the error case.
- usrbinbash 3y ago> Throw an error and move on with your life No, absolutely not! Panics are the result of conditions that absolutely should crash the program! They are not errors, they are not similar to exceptions, they are conditions that should not occur, and thus if they do occur, either the program itself, or the platform it is running on, has a problem that needs to be solved before the program runs again. If a cars fuel is running low, it should turn on a warning light and inform the driver that he should find a gas station. If a piece of the road is suddenly missing, the car needs to stop. If a panic occurs, I don't WANT the program to continue executing! That would lead me right back into C land, where an out-of-bounds memory access would silently start to poison my program and crash it days after the actual error ocurred, if i'm lucky! If I'm unlucky, and the process needs to be sufficiently privileged, it would kill the server, again several days (or weeks) later, with slim-to-no chance for me to figure out what even went wrong.
- zoky 3y agoAnd why exactly do you trust a called method to determine whether or not you should be able to keep running? Like… do your job, you object. I didn’t load your library and call a method on you to tell me what the state of my system is, I just want you to either do what I asked you to do or fail gracefully, and then I can decide whether we crash or not. > If a piece of the road is suddenly missing, the car needs to stop. Uh, no. If a piece of the road is missing, it’s up to the driver to stop, not the car. The car has no business whatsoever determining whether the road exists or not, except inasmuch as it communicates to the driver “hey, whatever the heck this is is difficult or impossible to drive on, your call what we do though.”
- zozbot234 3y ago> I just want you to either do what I asked you to do or fail gracefully, and then I can decide whether we crash or not. Then you're looking for resumable conditions, which just so happen to be effectively isomorphic to async-await. (The called function is effectively a piece of async code which 'awaits' upon a failure condition, after which it can either be resumed or canceled as with an ordinary panic.)
- 3y ago