A Bucket Of Sand

Recently I wanted to deploy a service of marginal trustworthiness, namely synapse, the reference server application for the Matrix protocol. More precisely, I wanted to deploy synapse on boxes I already had for economic reasons. Since I do consider it not fully trustworthy (it being network-facing and monolithic and all) there were some safeguards that needed taking. Among other things I wanted to be sure that synapse would not interfere with other services on the same box in ways it could not have done had it lived on a separate machine.

“Great!”, I hear the internet say, “Just dockerize it and everything will be fine!”. If only it were that simple.

Ferrous Oxide For Jaguars And Incremented Crocodiles

Caveat lector: the primary purpose of the article is to introduce a reader proficient in one of the popular object-oriented languages how not to program in Rust. While each feature of the language will be briefly introduced where it is used, no great efforts will be made to explain the feature in detail. Links to the Rust book should provide that.

That being said, let’s jump into the pit.

On Error Handling

Error handling is something we all have to do. Error handling is hard, and there are just so many times we think we know that some piece of code just cannot fail. So why check for errors there?

Well …

Your chdir() could fail because the target was deleted, causing your program to dump files somewhere in the failesystem. Your log2() could fail because your input was negative for some reason, summoning nasal demons as it fails. Your spacecraft guidance system could crash, causing your spacecraft to crash and burn as well. (This has happened.) All that just because error handling is hard, or expensive, or <insert other reason here>.

All because error handling sucks. But why is that so?

Static Noexcept Checking

C cannot be said to be a language that supports its users along all paths they may take. It is notoriously hard to write memory-safe programs (as the myriad CVEs we see every year make clear). Error handling in the C standard library relies on in-band signaling of error conditions and a very limited set of error numbers to communicate what went wrong. Indirectly called functions can either be not generic or receive void* arguments and cast them like maniacs—look no further than qsort.

But the one thing C has that actually does help programmers in a meaningful way is const.