00. How to use do, catch, try, throws in Swift?

It will take about 5 minutes to finish reading this article.

Although these keywords are not new to Swift, they are almost always used when using Swift Concurrency. Before we introduce the formal Concurrency content, let’s take a look at these keywords specifically.
In this article, we will introduce do-catch blocks, try, try? And try! The difference between them, as well as an introduction to throw.

1. how to use do-catch-try-throws in Swift

A do-catch statement is a mechanism for handling errors that allows you to write blocks of code that catch and handle possible errors. The general form of the do-catch-try-throws statement is as follows:

1
2
3
4
5
6
7
8
9
10
11
func someFunction() throws {
// Code that may throw errors
}

do {
try someFunction()
} catch pattern {
// Code that executes after a specific type of error is caught
} catch pattern {
// Another type of error is caught
}

Do code block:
In this block, you can place code that may throw erros.
Catch code block:
This is where errors are caught and handled. You can use different patterns based on the error type to catch errors and execute the appropriate code when matched. You can have multiple catch blocks that handle different types of errors.
Here is an example of how to use do-catch statement:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func verifyValueValidity(_ value: Int) throws -> Int {

if value < 0 {
print("Value is too small.")
throw CustomError.valueTooSmall
} else if value > 100 {
print("Value is too large.")
throw CustomError.valueTooLarge
} else {
print("Value is within acceptable range.")
return 1
}

}

do {
let valid1 = try verifyValueValidity(50)
// let valid2 = try verifyValueValidity(500)
} catch CustomError.valueTooSmall {
print("Value is too small.")
} catch CustomError.valueTooLarge {
print("Value is too large.")
} catch {
print("An error occurred: \(error)")
}

Note:
if there are multiple try Code in the do statement in the above code, for example:

1
2
3
4
5
6
7
8
9
10
11
12
do {
let valid1 = try verifyValueValidity(50)
let valid2 = try verifyValueValidity(500)
let valid3 = try verifyValueValidity(5000)//Will not execute
let valid4 = try verifyValueValidity(2500)//Will not execute
} catch CustomError.valueTooSmall {
print("Value is too small.")
} catch CustomError.valueTooLarge {
print("Value is too large.")
} catch {
print("An error occurred: \(error)")
}

Then the try statements will be executed in order, and if a statement hits the catch statement below it, it will stop and the following try statements will not be executed. The result of the execution of the above code:

1
2
Value is within acceptable range.
Value is too large.

2. try?and try!

There is a solution about the problem of the execution of exmultiple try statements. as following:
One solution to the above multiple try execution problem is to use try?. As follows is the sample code:

1
2
3
4
5
6
7
8
9
10
11
12
13
do {
let valid1 = try? verifyValueValidity(50)
let valid2 = try? verifyValueValidity(500)
let valid3 = try? verifyValueValidity(5000)
let valid4 = try? verifyValueValidity(2500)

} catch CustomError.valueTooSmall {
print("Value is too small.")
} catch CustomError.valueTooLarge {
print("Value is too large.")
} catch {
print("An error occurred: \(error)")
}

The results of the execution are as follows:

1
2
3
4
Value is within acceptable range.
Value is too large.
Value is too large.
Value is too large.

The result of the execution shows that all the try statements are executed, but written this way Xcode will give you a Warning:

1
'catch' block is unreachable because no errors are thrown in 'do' block

Like this:

That’s right, try? will invalidate the catch statement so that all the try statements will be executed. So the above code can just be simplified to:

1
2
3
4
let valid1 = try? verifyValueValidity(50)
let valid2 = try? verifyValueValidity(500)
let valid3 = try? verifyValueValidity(5000)
let valid4 = try? verifyValueValidity(2500)

So, when we don’t care about the execution of the catch statement, this is the way to write it.

Note:
If you change try? to try!, the catch statement will also fail, but if the forced parsing fails, it will cause a Crash, so it is not recommended.