The catch clauses don’t have to handle every possible error that the code in the do clause can throw. If none of the catch clauses handle the error, the error propagates to the surrounding scope. However, the propagated error must be handled by some surrounding scope. In a nonthrowing function, an enclosing do - catch clause must handle the error. In a throwing function, either an enclosing do - catch clause or the caller must handle the error. If the error propagates to the top-level scope without being handled, you’ll get a runtime error.
I think the last sentence should say "you'll get a compile-time error"? Unless this is referring to the top-level scope in something like Swift Playgrounds, etc, which have their own rules about what's allowed in the outer scope.
I guess I am missing something in the exception handling. How can you throw and not catch? I thought the whole point of exception handling in Swift is that it's checked, so any code that would throw and not catch won't build:
And if you use try! and an exception occurred, the runtime error is due to you attempting to use a variable without a value (rather than due to the exception propagating to the top level without being caught).
Yes. That is what “top‐level” means. If at runtime an error propagates all the way back out to the top‐level scope (such as main.swift) there will be a runtime error. The following compiles fine but throws a runtime error:
$ swift run Package
Fatal error: Error raised at top level: Package.(unknown context at $10155fb74).(unknown context at $10155fb9c).MyError(): file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1100.8.280/swift/stdlib/public/core/ErrorType.swift, line 200
zsh: illegal hardware instruction swift run Package
$ echo $?
Basically the point of the sentence is that the top‐level scope has built‐in catch‐like functionality that fatalErrors for you automatically. In a way, your entire program is wrapped in an external do‐catch of Swift’s own making.