Most error handling just consists of checking the return value of a call and propagating it up to the caller if necessary. Sometimes I also set an errno-like variable with an error message to check it in the top-level code. It's a bit wordy but obvious and sufficiently good for all my use cases.
I don't think C limits the size of the project. It's all about good organization and coming up with the right higher-level protocols/conventions. This, IMHO, is what allows or prevents the code size from scaling gracefully.