Java had a very bad model of checked exceptions (the OP was written in 2008). A correct way is to make it a part of the type system, though it doesn't have to be a sum type like Rust, and make any error-related code path as convenient as possible to use.
> In C, you are forced to perform the NULL-check, or crash.
You don't necessarily crash if you failed to perform a NULL check! That's literally the single biggest problem with C's undefined behaviors. C looks like forcing checks only because most programmers do understand crashes are bad, so they do prepare for trivial or demonstrated crashes. But that's not guaranteed, and they can't easily prepare for non-crash failures without additional tools.