📜 ⬆️ ⬇️

Introduction to error handling in Swift 3

Today we have prepared a translation for those who, just like the author of the article, while studying the Documentation of the Swift programming language avoid the chapter “Error Handling”.

From the article you will learn :




My history
')
When I was younger, I started learning the Swift language documentation. I read all the chapters several times, except for one: “Error Handling”. Somehow it seemed to me that I needed to be a professional programmer in order to understand this chapter.

I was afraid of error handling. Words like catch, try, throw, and throws seemed meaningless. They just scared. Do they not look frightening for the person who sees them for the first time? But do not worry, my friends. I am here to help you.

As I explained to my thirteen-year-old sister, error handling is just another way to write an if-else block to send an error message.

Error Message from Tesla Motors

As you probably know, Tesla cars have an autopilot function. But, if the machine fails for any reason, it asks you to take the wheel in your hands and reports an error. In this lesson we will learn how to display such a message using Error Handling.

We will create a program that will recognize objects such as traffic lights on the streets. To do this, you need to know at least machine learning, vector calculus, linear algebra, probability theory and discrete mathematics. Joke.

Introduction to the if-else statement

To get the most out of Error Handling in Swift, let's look back in time. Here's what many, if not all, novice developers would do when faced with an error message:

var isInControl = true func selfDrive() { if isInControl { print("You good, let me ride this car for ya") } else { print("Hold the handlebar RIGHT NOW, or you gone die") } } selfDrive() // "You good..." 

Problem

The biggest problem is the readability of the code when the else block becomes too bulky. First, you will not understand whether the function itself contains an error message until you read the function from beginning to end or if you do not call it, for example, selfDriveCanCauseError, which also works.

See, the function can kill the driver. It is necessary to warn your team in unequivocal terms that this function is dangerous and can even be fatal if you do not pay attention to it.

Another problem can be encountered when performing some complex functions or actions inside an else block. For example:

 else { print("Hold the handle bar Right now...") // If handle not held within 5 seconds, car will shut down // Slow down the car // More code ... // More code ... } 

The else block is swelling up, and working with it is like trying to play basketball in winter clothes (in truth, I’m doing this because it’s cold in Korea). Do you understand what I'm talking about? It is ugly and unreadable.

So you could just add the function to the else block instead of direct calls.

 else { slowDownTheCar() shutDownTheEngine() } 

However, the first of the problems I have highlighted remains, plus there is no definite way to indicate that the selfDrive () function is dangerous and that it should be handled with care. Therefore, I propose to dive into Error Handling to write modular and accurate error messages.

Meet the Error Handling

By now, you already know about the If-else problem with error messages. The example above was too simple. Let's assume that there are two error messages:

  1. you get lost
  2. car battery is discharged.

I'm going to create an enum that conforms to the Error protocol.

 enum TeslaError: Error { case lostGPS case lowBattery } 

Honestly, I don’t know exactly what the Error Protocol does, but without error handling, you can’t do without it. It's like: “Why does the laptop turn on when you press a button? Why can I unlock the phone screen by swiping my finger over it? ”

Swift developers have decided so, and I do not want to wonder about their motives. I just use what they did for us. Of course, if you want to understand more, you can download the software code Swift and analyze it yourself - that is, by our analogy, disassemble a laptop or iPhone. I'll just skip this step.

If you are confused, tolerate a few more paragraphs. You will see how everything becomes clear when TeslaError turns into a function.

Let's first send the error message without using Error Handling.

 var lostGPS: Bool = true var lowBattery: Bool = false func autoDriveTesla() { if lostGPS { print("I'm lost, bruh. Hold me tight") // A lot more code } if lowBattery { print("HURRY! ") // Loads of code } } 

So, if I ran this:

 autoDriveTesla() // "HURRY! " 

But let's use Error Handling. First of all, you must explicitly indicate that the function is dangerous and may generate errors. We will add the throws keyword to the function.

 func autoDriveTesla() throws { ... } 

The function now automatically tells your teammates that autoDriveTesla is a special case and they don’t need to read the entire block.

Sounds good? Great, now it’s time to issue these errors when the driver encounters a lostGPA or lowBattery inside the Else-If block. Remember about enum TeslaError?

 func autoDriveTesla() throws { if lostGPS { throw TeslaError.lostGPS } if lowBattery { throw TeslaError.lowBattery } 

I'll catch you all

If lostGPS is true, then the function will send TeslaError.lostGPS. But what to do next? Where are we going to insert this error message and add code for the else block?

 print("Bruh, I'm lost. Hold me tight") 

OK, I don't want to overwhelm you with information, so let's start with how to execute a function when it has the throws keyword.

Since this is a special case, you need to add try inside the do block when working with this function. You are: "What?" Just follow the course of my thoughts a little bit more.

 do { try autoDriveTesla() } 

I know that you are thinking now: “I really want to display my error message, otherwise the driver will die.”

So where will we put this error message? We know that the function is capable of sending 2 possible error messages:

  1. TeslaError.lowBattery
  2. TeslaError.lostGPS.

When the function gives an error, you need to “catch” it and, as soon as you do, display the corresponding message. It sounds a bit confusing, so let's see.

 var lostGPS: Bool = false var lowBattery: Bool = true do { try autoDriveTesla() } catch TeslaError.lostGPS { print("Bruh, I'm lost. Hold me tight") } catch TeslaError.lowBattery { print("HURRY! ") } } // Results: "HURRY! " 

Now everything should be clear. If not everything is clear, you can always watch my video on YouTube .

Error Handling with Init

Error handling can be applied not only to functions, but also when you need to initialize an object. Suppose if you did not specify the name of the course, then you need to give an error.



If you enter tryUdemyCourse (name: ""), an error message appears.

When to use Try! and try?

Good. Try is used only when you execute a function / initialization inside a do-catch block. However, if you have no purpose to warn the user about what is happening, displaying an error message on the screen, or somehow fix it, you do not need a catch block.

try? - what is it?

Let's start with try? Although not recommended,

 let newCourse = try? UdemyCourse("Functional Programming") 

try? always returns an optional object, so you need to retrieve newCourse

 if let newCourse = newCourse { ... } 

If the init method throws an error, like

 let myCourse = try? UdemyCourse("") // throw NameError.noName 

then myCourse will be nil.

try! - what is it?

Unlike try? it returns not an optional value, but an ordinary one. For example,

 let bobCourse = try! UdemyCourse("Practical POP") 

bobCourse is not optional. However, if the initialization method gives an error like,

 let noCourseName = try! UdemyCourse("") // throw NameError.noName 

then the application will crash. As with forced extraction with!, Never use it unless you are 101% sure what is happening.

Well that's all. Now you and I understand the concept of Error Handling. Simply and easily! And do not need to become a professional programmer.

Source: https://habr.com/ru/post/320940/


All Articles