3 ms·
>To be concrete, let's talk about an example of a panic. Say you want to access the 3rd element of a vector. There are two cases: Reality is not that simple, i
by simion314 4y ago
>To be concrete, let's talk about an example of a panic. Say you want to access the 3rd element of a vector. There are two cases:
Reality is not that simple, if you worked in this industry you would know. For example I was building a web scraper years ago and the WebView would crash since is C/C++ , instead of doing it's job and show a web page or a broken web page it crashed my entire program,. The solution was to split my program in a parent program and a child program so this bug does not bring my entire thing down, and I can crash the issue and record the bad url that crashes and try again or just skip it.
I would hate to use Rust libraries that would crash my entire program if they for some reason are bugged. In my experience I found bugs in many popular libraries. So in Rust if I import a say library to resize an img and say the img is corrupted and library is shit it will crash my entire program? I would prefer a higher language where I can try=crash the image resize function and if shit goes wrong I can show the user a relevant message , or fallback to some other resizing method.
- notriddle 4y agoYou need to run it in a separate process. Rust does not have good enough fault isolation features to safely assume a buggy image processor won’t break your app. * Entering an infinite loop can bring down everything. A separate thread might not, but since Rust provides no way to kill a thread without it cooperating, there is no way to stop a stuck thread without bringing down the whole process. * Stack overflow is an instant abort, not a panic. * Double panic, where panicking calls a destructor that itself panics, is an instant abort.
- simion314 4y agoQuestion, if you are a library/program author why would you intentionally use a panic and not cleanup and return an error? Maybe I misunderstood and in fact good developers never trigger panics unless there is no way to avoid it, like if they could not prevent it with more checks or is it impossible to cleanup because they already fucked up, wrote garbage in the process memory and safest thing is to kill the process.
- oconnor663 4y agoI think there are a few cases where Rust likes to panic, but different people probably have different opinions here: - Extremely common operations with dedicated syntax, where introducing error handling would be burdensome. Things like array indexing or arithmetic overflow. In these cases, you usually want an alternative, fallible way to do the same operation. - Cases where most callers will probably convert the error into a panic anyway. One example of this might be .split_at() on slices, which is bounds-checked just like an array access. Most callers would probably just .unwrap() the out-of-bounds case, and callers who don't want it to panic can easily check before the call, so it's more ergonomic to panic. - Cases where the only plausible reason for failure is a bug in the caller. For example, the .borrow() and .borrow_mut() methods on RefCell will panic if a write overlaps with another read or write. The caller is almost always expected to statically guarantee that that doesn't happen, usually by making all borrows short-lived. (And here again there are fallible alternatives available.) An interesting example of something that doesn't panic, but which probably should, is taking a mutex. The standard mutex in Rust includes a "poisoning" mechanism, which almost every caller just .unwrap()s. I think the majority opinion these days is that poisoning should just be removed, but given that it's around I think most people wish it just panicked instead of returning a Result.
- notriddle 4y ago> is it impossible to cleanup because they already fucked up, wrote garbage in the process memory and safest thing is to kill the process That’s essentially it, yes. My code should never actually panic. If it does, it means the state of the process has become deeply diseased, and attempting to “clean up” is likely to just make things worse. Of course, if it’s safe Rust, then it still won’t write past the end of a buffer or anything disastrous like that, but buggy code is still buggy code and there’s lots of stuff Rust won’t stop you from doing. One of the more extreme things I’ve done in production Rust code was add a “watchdog thread”. It has a channel that takes unit and receives on a timeout, and the thread doing the actual work is expected to send it a message once a minute. If it doesn’t receive a message within a minute, it hard aborts the process. The default setup is run under a service manager like systemd to make sure it gets restarted, and that failures are actually logged somewhere. This is meant to solve the problem that safe Rust is a Turing complete language, so is subject to the halting problem. The type checker can prove that you won’t read past the end of a buffer, but it cannot prove that your code will ever actually finish running. Which means, if you have a project like a web scraper that needs high uptime, you need to prevent it from getting stuck somehow.
- golergka 4y ago> I would hate to use Rust libraries that would crash my entire program if they for some reason are bugged. You would, but for other programs with other requirements it would actually be beneficial. There's no single right answer, and you should pick the library that follows your particular requirements for that particular program.
- oconnor663 4y ago> I would prefer a higher language where I can try=crash What you're describing is the `catch_unwind` mechanism that Rust does have. Because panics are implemented with unwinding (by default), you can catch them. But it's not the normal error handling mechanism; it's the "oh god an assert just failed, or we just OOMed or something, who knows, most bets are off" mechanism. If you have a main loop that's sufficiently isolated from individual tasks, such that you think you can do something useful with the fact that one of your tasks just vanished in a puff of smoke, then catching a panic coming out of a task might be a reasonable thing to do. That often makes sense in server code, where your main loop might want to keep trucking, or at least gracefully shut down other connections. But for most library code, the right thing to do is to allow most panics to propagate and crash the caller.
- simion314 4y agoSo for example in JS a correct regex can throw exception on some input , so in the places where this can happen we can use a try catch . What do you do in Rust , do you check the return result and on top of that do you try to catch a panic just in case the regex library is bugged ? so you have to implement everywhere 2 error handling methods to be 100% safe? If yes seems more ugly to have to implement 2 error catching ways. YEs it happen to me many times to hit bugs when working in real world, bugs in image libraries, bugs in regex libraries, bugs in pdf libraries, bugs in html/xml parsers so from my experience working with c/c++ and higher level languages I prefer the higher level languages, less bugs, almost no complete crashes and better error reports from the exceptions. I never had the tiem to try Rust but I am not tempted so far.
- kaba0 4y agoThere is no 100% safe anywhere. Does your JS code handle out of memory errors with try-catch? No, it will abort as if nothing happened at all. Sure, there are bugs in every code but unexpectedly panicking is considered a bug in a library so in my not too extensive experience with rust libs, these are not the norm at all. So simply writing code where you yourself don’t panic should give you quite a high chance of not hitting this case ever.