The return type of a function is always handled by its direct caller and only by its direct caller.
Exceptions are fundamentally different because they aren't necessarily handled by the caller, but by the nearest appropriate exception handler, wherever it is, regardless of scope.
That is both their strength when they are used appropriately, and their weakness when they are not.
You're right in that the implicit bit extends all the way up the call stack. They aren't the same in practice, just in theory.
That implicit parallel 'track' is useful in doing the Foo => Result<Foo, Error> for you in the form of Result<Foo, Exception> but bad in not warning of unmatched values and hiding the fact. Like many a tool it can be abused by those who know just enough to use it but not enough to know why.
This is why Java originally forced you to make thrown exceptions explicit. This railway approach is one good way of dealing with error conditions explicitly.
The return type of a function is always handled by its direct caller and only by its direct caller.
Exceptions are fundamentally different because they aren't necessarily handled by the caller, but by the nearest appropriate exception handler, wherever it is, regardless of scope.
That is both their strength when they are used appropriately, and their weakness when they are not.