
One thing I've noticed over the years is that in many chess engines, error handling doesn't seem to be much of a thing.
Very often only the happy path is written. For example: if a UCI-string containing an error comes in, the engine will crash. If UCI-commands are given in a wrong order and/or omitted, it can happen that the engine expects to have received a command but didn't, and will crash on the subsequent command.
I'm noticing this again while writing my Texel tuner (*). I've read through a few tuners with a cursory glance, but most basically just read the data file, and assume that all data is 100% correct. Therefore the tuner might end up with corrupted FEN-strings and crash (or in the better way, skip the position).
In short, a rather large part of the code in my engine consists of error handling. (In Rust, you can NOT just SKIP error handling without jumping through hoops. You MUST handle any possible error, or specifically state that you won't.) Thus I check and sanitize all the data that comes into the engine; be it UCI-commands, typed at the keyboard on the command-line, or when reading the tuning data file. The engine should therefore always either reject incoming stuff and do nothing, or be working with correct data.
Do you spend time in error checking everything, or do you assume that some stuff will just be correct? For example: UCI: assume the GUI will do it correctly, tuning data: no need to check because I'm the only one making the data.
Not having to do the error checks would make writing the code about twice as fast, and half as long...
(*) It is actually much less difficult than I thought. I've FINALLY taken the time in my Christmas holiday to read up on everything I collected over the years. Now that I know what steps to take, writing the code to do so is rather easy. Stuff that stumped me in the past were sentences such as: "Create a vector of mutable coefficients." Darn. Just write "make a list of the variables you want to tune."