mozeryansky
(Michael Ozeryansky)
1
I don't like to nest my code whenever possible and I prefer to return early. To accomplish this with try/catch blocks the syntax looks funky and verbose.
Instead of placing all the positive flow code within the do, I will define the variable and bundle up the throwing portion into its own do/catch with an early return on error. Then after the throwing portion I continue with the logic. In complex applications you can imagine multiple of these try/catch blocks keeping the nesting to 1 level, instead of increasing the level each time.
func throwingFunc() throws -> Int {
return 0
}
func example() {
let value: Int
do {
value = try throwingFunc()
} catch {
print("Do something with \(error)")
return
}
doSomething(with: value)
...
}
I would like new Swift syntax to be able to accomplish this more succinctly.
Some possible solutions:
// do without defining a block
do let value = try nilThrowingFunc() catch {
print("Do something with \(error)")
return
}
// guard acting like do, enforcing return on catch and unwrap
guard let value = try throwingFunc() else {
print("value is nil")
return
} catch {
print("Do something with \(error)")
return
}
// do returns inner value like `DispatchQueue.sync()`
let value = do {
return try throwingFunc()
} catch {
print("Do something with \(error)")
}
...
The main purpose really is to define value in the same scope as where I'm calling try. Is there any current discussions on this? What does everyone think?
13 Likes
nnnnnnnn
(Nate Cook)
2
I would love this syntax — the ceremony around do/catch right now makes it frustrating to handle errors from multiple calls to throwing functions. I believe this pitch/proposal is the deepest exploration of the issue.
9 Likes
I think the syntax is very confusing. Either the keyword is always followed by a closure, or it is always followed by a block, but we really should not mix them.
do {
return try throwingFunc() // return applies to outer scope.
} catch { … }
let value = do {
return try throwingFunc() // return applies to inner scope.
} catch { … }
Jon_Shier
(Jon Shier)
4
guard / catch will be even more useful with the Swift Concurrency work, given the prevalence of try await in most of the examples (and my own test usage).
2 Likes