The difference is that callers (even indirect callers) can register handlers to handle those errors without unwinding the stack.
Maybe the error handler makes it return a default value. Maybe it will deallocate a cache to free up memory in a memory-constrained situation. Maybe it purely ignores EOF or a FILE DOES NOT EXIST error where those do not matter.
I also have a special error handler for parsing. If the error is a parse error, it prints the parse error in standard format, with source file, line, etc. Otherwise, it passes the error on to the next error handler in the chain.
This helps me modularize my code by keeping the parse error concerns separate from error handling for everything else.