Chapter 8. Paths Less Traveled – Error Handling

One of the biggest changes in Swift 2 is that Apple added a feature called error handling. Handling error situations is often the least fun part of programming. It is usually much more exciting to handle a successful case, often referred to as the happy path because that is where the exciting functionality is. However, to make a truly great user experience and therefore a truly great piece of software, we must pay careful attention to what our software does when errors occur. The error-handling features of Swift help us in handling these situations succinctly and discourage us from ignoring errors in the first place.

In this chapter, we will discuss exactly what error-handling features Swift has and how they help us to write better software. We will do so by covering the following topics:

  • Throwing errors
  • Handling errors
  • Cleaning up in error situations

Throwing errors

Before we talk about handling an error, we need to discuss how we can signal that an error has occurred in the first place. The term for this is throwing an error.

Defining an error type

The first part of throwing an error is defining an error that we can throw. Any type can be thrown as an error as long as it implements the ErrorType protocol, as shown:

struct SimpleError: ErrorType {}

This protocol doesn't have any requirements, so the type just needs to list it as a protocol it implements. It is now ready to be thrown from a function or method.

Defining a function that throws an error

Let's define a function that will take a string and repeat it until it is at least a certain length. This will be very simple to implement but there will be a problem scenario. If the passed in string is empty, it will never become longer, no matter how many times we repeat it. In this scenario, we should throw an error.

Any function or method can throw an error as long as it is marked with the throws keyword, as shown in the following code:

func repeatString(
    string: String,
    untilLongerThan: Int
    ) throws -> String
{
    // TODO: Implement
}

The throws keyword always comes after the parameters and before a return type.

Implementing a function that throws an error

Now, we can test if the passed in string is empty and throw an error if it is. To do this, we use the throw keyword with an instance of our error:

func repeatString(
    string: String,
    untilLongerThan: Int
    ) throws -> String
{
    if string.isEmpty {
        throw SimpleError()
    }

    var output = string
    while output.characters.count <= untilLongerThan {
        output += string
    }
    return output
}

An important thing to note here is that when we throw an error, it immediately exits the function. In the preceding case, if the string is empty, it goes to the throw line and then it does not execute the rest of the function. In this case, it is often more appropriate to use a guard statement instead of a simple if statement, as shown in the following code:

func repeatString(
    string: String,
    untilLongerThan: Int
    ) throws -> String
{
    guard !string.isEmpty else {
        throw SimpleError()
    }

    var output = string
    while output.characters.count < untilLongerThan {
        output += string
    }
    return output
}

Ultimately this doesn't act any differently from the previous implementation, but it reiterates that the rest of the function will not be executed if it fails the condition. We are now ready to try to use the function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset