Currently, we have the option to handle throwing functions by converting their errors to nil when the function throws:
try? someThrowingFunction()
// or
let results = try? someThrowingFunction()
Pitch
My pitch is to allow catch to be declared after a throwing function with a preceding try? keyword to expose any resulting error:
try? someThrowingFunction() catch {
print("Caught error: \(error)")
}
guard try? someThrowingFunction() else catch {
print("Caught error: \(error)")
return
}
When the throwing function has a return value, the following would apply:
let results = try? someThrowingFunction() catch {
print("Caught error: \(error)")
}
guard let results = try? someThrowingFunction() else catch {
print("Caught error: \(error)")
return
}
The current functional equivalents to the preceding is:
do { try someThrowingFunction() } catch {
print("Caught error: \(error)")
}
do { try someThrowingFunction() } catch {
print("Caught error: \(error)")
return
}
When the throwing function has a return value:
var results: ResultsType?
do { results = try someThrowingFunction() } catch {
print("Caught error: \(error)")
}
var results: ResultsType?
do { results = try someThrowingFunction() } catch {
print("Caught error: \(error)")
}
guard let results = results else { return }
4 Likes
I like the guards, I was looking for something exactly like this (in an attempt to reduce a pyramid of do/catch).
sveinhal
(Svein Halvor Halvorsen)
3
Not sure if I'm in love with the try? catch syntax, but I like the guard version, possibly without the question mark:
guard let result = try throwingFunction() else catch {
print("Caught error: \(error)")
return
}
7 Likes
This syntax won't work because if the function throws an error, then results won't be bound and can't be accessed below this block.
1 Like
rintaro
(Rintaro Ishizaki)
5
You don't need to use var and Optional in this case:
let results: ResultsType
do {
results = try someThrowingFunction()
} catch {
print("Caught error: \(error)")
return
}
1 Like
results isn’t available outside of the do block. And that, perplexingly enough, will not do.
I like the pitch.
jevonmao
(Jevon Mao)
7
I support this pitch. do/catch blocks are probably one of my least favorite part about Swift's error throwing. As long as the do/catch block syntax remains supported so it don't break existing APIs, I don't see any downsides to adding this syntactic sugar that will make Swift less redundant and more readable.
I really like the pitch especially the guard example. The current do / catch syntax adds a lot of noise for me. It is nice to use do catch for a batch of calls that have try but for a single try call I really would like your guard approach.
GreatApe
(Gustaf Kugelberg)
9
It's a bit confusing though, it looks like throwingFunction is optional. And what if it is?
2 Likes
Could you describe the reason for preferring try? instead of try ? The semantics seem to be closer to the existing semantics of try with the change being that catch is now allowed in more places, rather than try? (which discards the error).
3 Likes