In swift, error handling is the process that is used to respond and recover from error conditions in the application. Swift provides us the support to capture and manipulate errors in an application at runtime.
Generally in swift, the major things which cause to fail our code are user input, connections, and links associated with our code. Suppose if we make a calculator app in which we can perform a calculation of two numbers and it works fine when we entered valid numbers as an input, but when the user enters invalid input like an entered string instead of number then our code will fail and gives an error.
In this situation, we need to catch these kinds of errors and display a valid message to the user like “invalid input”.
By using the error handling process in swift we can capture the errors thrown by an application and perform some custom operations to show custom messages to the user based on our requirements.
Generally, in swift errors are represented by the value of types that follow the standards of Error
protocol. The Error
protocol tells the compiler that any data structure which compiles to the protocols can be used for error handling purpose.
In swift, enumeration is the best suit for grouping error conditions. We can represent or declare our errors in enumeration by its name and value.
Following is the sample way of defining custom errors in the swift enumeration.
enum UserError : Error {
case InvalidId
case InvalidName
}
We can throw an error when the normal flow of application cannot continue or something unexpected is happing like as shown below
throw UserError.InvalidId
Following is the example in which we declare our custom errors in enumeration and throwing errors when the normal flow of execution fails and catching exceptions using do…catch
statements.
enum UserError : Error {
case InvalidId
case InvalidName
}
func userdetails(id : Int, name: String) throws
{
if id == 0 {
throw UserError.InvalidId
}
if name == "" {
throw UserError.InvalidName
}
}
do {
try userdetails(id: 0, name: "Suresh")
} catch UserError.InvalidId {
print("Invalid Id")
}
catch UserError.InvalidName {
print("Invalid Name")
}
If you observe above example we added a custom errors to enumeration and throwing an exceptions when it failed to match certain defined conditions.
When we run the above program in swift playground we will get a result like as shown below
This is how we can represent and throw errors in a swift programming language based on our requirements.
In swift, when the application throws an error we need to write our custom piece of code to handle the exception errors like showing custom error message about failure or an alternative way to proceed further in the application.
Generally, in swift we can handle the errors in different ways like
do…catch
statementIn swift, we can identify the places of throwing an error in our code by using try or try? or try! Keywords just before the code that calls the function, method or an initializer that can throw an error.
Now we will see how to handle errors in application using different ways in swift programming language.
In swift we can indicate a function, method or initializer can throw an error by adding throws
keywords in the function declaration and after its parameters. In case the function is having return type then we need to write a throws
keyword just before the return arrow (->). A function which is marked with throws
keyword is called a throwing function.
Following are syntaxes of defining a function with or without throws
keyword.
func functioncanThrowError() throws -> String
func functioncannotThrowError() -> String
Following is the example of defining a function with throws
keyword to throw an exception when invalid parameters sent in function.
enum UserError : Error {
case InvalidId
case InvalidName
}
func userdetails(id : Int, name: String) throws
{
if id == 0 {
throw UserError.InvalidId
}
if name == "" {
throw UserError.InvalidName
}
}
try userdetails(id: 0, name: "Suresh")
If you observe above example we added a custom errors to enumeration and throwing an exceptions when it failed to match certain defined conditions using throw keyword and identifying the places of throwing an error using try
keyword.
When we run above program in swift playground we will get a result like a shown below
This is how we can handle errors in an application using throw
keyword based on our requirements in swift programming language.
In swift, we can handle errors using do…catch
block of code. If any error occurs in do code block it will check for matched catch block to determine which catch block of code can handle the error.
Following is the syntax of defining a do…catch
block to handle errors in swift programming language.
do {
try expression
statements
} catch pattern 1 {
statements
} catch pattern 2
statements
} catch pattern n where condition {
Statements
}
First, in do block the required function or method will be called by using try keyword. If any error occurred while executing the required function or method it will go to catch blocks and executes matched catch block to execute based on the defined conditions.
Following is the example of using do..catch
blocks to handle errors in application.
let stud = ["BTech": "Suresh Dasari", "MD": "Trishika Dasari"]
enum CustomErrors: Error {
case NoName
case NoCourse
}
func UserDetails(names: [String: String]) throws -> String {
guard let check = names["MD"] else {
throw CustomErrors.NoName
}
return check
}
do {
let user = try UserDetails(names: stud)
print("Name: \(user)")
} catch CustomErrors.NoName {
print("Name Not Exists")
} catch CustomErrors.NoCourse {
print("Course Not Exists")
}
If you observe above example we added a custom errors to enumeration and handling an exceptions using do…catch
code block and raising matched catch block based on defined conditions.
When we run above program in swift playground we will get result like as shown below
This is how we can use do…catch
blocks in swift programming language to handle errors based on our requirements.
In swift, we can convert errors into optional value by using try keyword with question mark (?) like try?. If any error occurred while evaluating try? expression, the value of the expression will become a nil.
Following is the example of converting errors into optional values by using try? In swift programming language.
let stud = ["BTech": "Suresh Dasari", "MD": "Trishika Dasari"]
enum CustomErrors: Error {
case NoName
case NoCourse
}
func UserDetails(names: [String: String]) throws -> String {
guard let check = names["TEST"] else {
throw CustomErrors.NoName
}
return check
}
let user = try?UserDetails(names: stud)
print("Name: \(user)")
If you observe above example we added a custom errors to enumeration and converting function exceptions to optional values using try with question (?) mark (try?).
When we run the above program in swift playground we will get a result like as shown below
In case if we didn’t use an optional try?, we will get an error in the application.
This is how we can convert exceptions into optional values in a swift programming language based on our requirements.
In some situations, we feel better throwing a runtime error instead of throwing a method or function. In those cases, we can use try! before an expression to disable error propagation. During execution, if no error occurred then try! will return the value in case if any error occurred, we will get a runtime error.
Following is the example of disabling an error propagation using try! In swift programming language.
let stud = ["BTech": "Suresh Dasari", "MD": "Trishika Dasari"]
enum CustomErrors: Error {
case NoName
case NoCourse
}
func UserDetails(names: [String: String]) throws -> String {
guard let check = names["TEST"] else {
throw CustomErrors.NoName
}
return check
}
let user = try! UserDetails(names: stud)
print("Name: \(user)")
If you observe above example we added a custom errors to enumeration and disabling error propagation using try!.
When we run above program in swift playground we will get a result like as shown below
In case if we didn’t use try! in our application it will throw an error which we defined instead of runtime error.
This is how we can disable error propagation in a swift programming language based on our requirements.
In swift, Defer
keyword provides functionality for execution of statements before code is executed and leaves the current block of code. We can use defer statement to check whether our file descriptor is closed and release from memory. Defer statement won't responsible to transfer the flow of program into another statement like break and return, defer works in reverse order its code executed at the end of code.
Following is the example of using defer in application to execute code block at the end of statements execution in swift programming language.
func Method() {
print("Message one Executed")
print("Message two Executed")
print("Message three Executed")
defer {
print("deferred block 3 Not Executed")
}
defer {
print("deferred block 2 Not Executed")
}
defer {
print("deferred block 1 Not Executed")
}
print("Message four Executed")
print("Message five Executed")
}
Method()
When we run above program in swift playground we will get result like as shown below
Message one Executed
Message two Executed
Message three Executed
Message four Excuted
Message five Excuted
deferred block 1 Not Executed
deferred block 2 Not Executed
deferred block 3 Not Executed
If you observe above example defer
keyword code blocks executed at the end of statements.
This is how we can specify cleanup actions in swift programming language based on our requirements.