This paper surveys the error-handling world, analyzes various ideas which have been proposed or are in practice in other languages, and ultimately proposes an error-handling scheme for Swift together with import rules for our APIs.
I've heard people talk about explicit vs. implicit propagation. I'm not going to use those terms, because they're not helpful: there are at least three different things about error-handling that can be more or less explicit, and some of the other dimensions are equally important.
What is an error? There may be many different possible error conditions in a program, but they can be categorized into several kinds based on how programmers should be expected to react to them. Since the programmer is expected to react differently, and since the language is the tool of the programmer's reaction, it makes sense for each group to be treated differently in the language.
To be clear, in many cases the kind of error reflects a conscious decision by the author of the error-producing code, and different choices might be useful in different contexts. The example I'm going to use of a "simple domain error" could easily be instead treated as a "recoverable error" (if the author expected automatic propagation to be more useful than immediate recovery) or even a "logic failure" (if the author wished to prevent speculative use, e.g. if checking the precondition was very expensive).