Hacker News new | ask | show | jobs
by simion314 1504 days ago
So 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.

2 comments

> 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 ?

Nope, we just check the return result because libraries usually don't crash and have well-defined error cases. Having a decent type system helps catching all the possible outcomes. In a few years coding Rust, i never had a single crash due to a library panic, only from explicit unwraps i applied in my own codebase.

Panics are not intended for errors, but for unrecoverable failures. For example, in rust std a failing memory allocation will crash your whole program, which is in most cases what you want to do. For the remaining cases, there are other non-fallible methods.

For example: String::reserve vs String::try_reserve or HashMap::insert vs HashMap::try_insert.

There 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.

>Sure, there are bugs in every code but unexpectedly panicking is considered a bug

Yes so would you like say Firefox to just crash when one of it's many dependencies crashes?

You are suggesting but I am not sure if I understand correctly that only memory errors cause panics? So what if the library reads a file and unexpectedly it shit happens with the file, it will crash the program because the developer maybe forgot to return a special error code in this case,

All the filesystem APIs return Results rather than panicking, since like you said it's expected for those to fail sometimes and for the program to handle those failures. It's possible for a library to convert those Results into panics by calling .unwrap() on them, but that would usually be considered a bad design (ok for tests and tiny programs though). So I think you have an important point here, which is that if your application is calling into a library that you worry might have some bad design decisions in it, you do have to worry about it bringing down your process. And maybe it could make sense in some rare cases to try to isolate that library with catch_unwind. But I think most Rust programmers would prefer to just fix the dependency. The fact that you can visibly spot a lot of these conversions in the code is helpful for auditing.

I'm not super up to speed on JS, but I might draw an analogy to Python. Handling a result in Rust is similar to catching an exception of a known type in Python, a very common thing to do. On the other hand, catch_unwind is (loosely) similar to writing a bare except clause that catches every conceivable exception. You can do that, and sometimes it's correct to do that, but in most cases it's a bad idea. You don't want to accidentally suppress errors that indicate a bug in your program.

Thanks, from my experience with desktop apps in managed language I alwas added a global catch for crashes that were not caught or can't be caught, there I was writing the details in a log file. Then I had a menu entry for submitting a bug report, a popup would open and the user had the option to include the log file with the exception information and details like operating system, runtime version etc. The only thing that was bringing down this app in the higher level language(it was an Adobe AIR app in Action Script 3) was the freaking Web View , because was a wrapper over WebKit and that was C++.

This days doing backend dev I am forced to move stuff in a different process but most stuff I use I prefer to use binaries then libraries , for example for resizing an image instead of using the built in image library that crashes sometimes and brings the script down I install image magic on the server and write a script for resizing an image then call that script and check it's output , sometimes I had to use the timeout linux program to kill the program if it gets stuck on some input file.

If I were to create that image resize library in Rust I would attempt to catch everything , including panics and return it as a error result(so only system crashes would be uncaught)

IO errors are generally handled by returning a `Result` type, that contains the details of the problem on error. You wouldn't use `panic` for IO errors. `panic`s are meant for dealing with broken invariants/assertion failures because of a bug in the program.