Handling errors is one tricky aspect of writing code. Error handling is the essential devil we simply can't do without.
The procedural world relies on returning error codes from functions, suffering from the same problem because of null checks. We could possibly miss checking. Also, the actual business logic gets lost in the tangled error handling code.
A case in point is file handling. Opening files and reading the contents, for example, could result in exceptions. As another example, the file may not exist (perhaps there is a typo in the filename), or it may not have requisite permissions.
Throwing an exception is a much better idea. The calling code cannot ignore it, at the very least it has to catch the exception.