But that is the point I was trying to make. No language can save you from logic errors, but a lot of languages let you recover from errors in functions. The simplest way is exception handling in Java like try { parse(xmlFile) } catch ( ... ) {.... }
There is no reason the device should get in an undefined state if parsing that file fails or even completely crash.
> There is no reason the device should get in an undefined state
That is impossible to guarantee. It isn't even possible to completely generally[†] test for - what you have there is a variant of the halting problem (https://en.wikipedia.org/wiki/Halting_problem).
[†] added "generically" there as it is possible, using formal methods from the start, to prove that a program is correct so will not error (in an unexpected manner) on any input, but such methods are time-consuming so outside of certain specific fields you'll not find them used
I'd argue that languages which force handling via the type system (e.g. `Result<T, Error>` in Rust) makes it less likely that bugs like this will go unhandled, since the position if the programmer does not explicitly opt out of error handling (with `unwrap` etc) is a compilation error rather than missing error handling.
In the case of an appliance device where the XML file was externally supplied? Continue as though the file never existed (and possibly also delete the XML file).
Unfortunately no language or other framework or system can completely do away with programming logic errors.