This is the kind of scenario that is served better by Go/C-style error values than exceptions. Error values facilitate and encourage you to log what you were doing at the precise point when an error occurs. Doing the same with exceptions idiomatically often requires an exception hierarchy or copious amounts of separate try/catches.
The difference really becomes apparent when trying to debug a customer's problem at 3am (IME).
Your stack trace tells you where in the code the error occurred, but doesn't tell you what it was doing with what data. For that you need to pass context for the error up the chain of calls, adding to it as you go up. Exceptions are not a great way of doing it as you only have the local context, which isn't a great help when you're catching N levels up.
And if you're not catching N levels up but catching at each level, then you are emulating error values but with try/catch blocks.
That is great for you as a developer. As a sysadmin supporting other people's crap, stack traces and heap dumps are useless beyond forwarding them to the vendor.
The difference really becomes apparent when trying to debug a customer's problem at 3am (IME).