Intro to Error Handling

Introduction

Welcome to Lesson 4, Intro to Error Handling, of The Swift Fundamentals. I feared Error Handling. I thought I had to be a professional debugger to fully utilize the feature. However, one day, I discovered, again. It’s nothing more than writing an else-if block to send and deal with the error messages you’ve designed on your own. The built-in features of Error Handling since Swift 2.0 allow you to write cleaner, modular, and readable code.

Problem

  1. How do you warn your co-workers the function may result unexpected outcomes?
  2. What is a do-try block?
  3. How do you distinguish between try?, try!, and try?

Design Safety Feature

Design a safety check for riders based on height. If the passenger is taller than 2m or below 1.4m, the program will send error messages along with other instructions.

  1. func checkHeight(height: Int) {
  2. if height > 200 {
  3. print("You are going to hit your head and fall off")
  4. // Take him/her off from the ride
  5. // Code ...
  6. // Seatbelt tighten
  7. } else if height < 140 {
  8. print("You might fly in the air")
  9. // Take him/her off from the ride
  10. // Code ...
  11. } else {
  12. print("Enjoy")
  13. // Take him/her to the ride
  14. // Code ...
  15. }
  16. }

Problem with Else-If alone

  1. Bloated function
  2. Lack of modularity
  3. Uncertainty

Error Handling

Error Handling is just additional way to write an else-if statement to not only deal with the error messages but also respond after them in a separate block.

Design Error

Create an enum that conforms to the Error protocol. Determine a few cases.

  1. enum HeightError: Error {
  2. case maxHeight
  3. case minHeight
  4. }

Any type that declares conformance to the Error protocol can be used to represent an error in Swift’s error handling system. Because the Error protocol has no requirements of its own, you can declare conformance on any custom type you create.

Design Throwable Function

Create a function that can throw/return errors by inserting throws at the end of the function parameter. The function does not contain error messages. Instead, it “throws” an error which will be “caught” and handled in a separate block with do-try.

  1. func checkHeightError(height: Int) throws {
  2. if height > 200 {
  3. throw HeightError.maxHeight
  4. } else if height < 140 {
  5. throw HeightError.minHeight
  6. } else {
  7. print("Enjoy your ride")
  8. }
  9. }

Call and Handle Error

To call a function that contains throws, the function requires try within a do block. A catch block is used to recognize and the error thrown by the function. If there is no error thrown, the catch block is ignored.

  1. do {
  2. try checkHeightError(height: 240)
  3. } catch HeightError.maxHeight {
  4. print("Get out of here")
  5. // Logic
  6. } catch HeightError.minHeight {
  7. print("Too short to ride")
  8. }

Error Handling with Object Initialization

Design Error

  1. enum NameError: Error {
  2. case noName
  3. }

Design Throwable Class

When the user enters an empty string when initializing, the init method throws NameError.noName.

  1. class Course {
  2. var name: String
  3. init(name: String) throws {
  4. if name == "" {
  5. throw NameError.noName
  6. } else {
  7. self.name = name
  8. print("You've created an object!")
  9. }
  10. }
  11. }

Initialize and Handle Error

Create an object using try within a do-catch block.

  1. do {
  2. let myCourse = try Course(name: "")
  3. } catch NameError.noName {
  4. print("Error: please make sure enter name!")
  5. // Logic
  6. }

Distinguish Between try?, try!, and try

try is only used within a do-catch block. However, try? and try! can be used without it.

You may get away using try without a do-try block within Playground, but it is not allowed in anywhere else.

try?

It returns an optional type. If it throws an error, the result will be nil.

  1. let newCourse = try? Course(name: "Bob the Dev") // returns Course?
  2. let newDopeCourse = try? Course(name: "") // nil

try!

It returns a normal type. If the method/init throws an error, it will crash.

  1. let myNewCourse = try! Course(name: "Bobby Lee") // ?
  2. let myDopeNewCourse = try! Course(name: "") // ☠️

Source Code

1004_intro_error_handling.playground

Resources

Intro to Error Handling by Bob the Developer

Conclusion

You’ve learned the Swift Error Handling syntax such as catch, do, and try. To recap, you may only use try within a do-catch block to execute a throwable method. However, you may also use try? and try! alone. Again, avoid using! in most cases since it will break your program. If you wish to review or feel stuck, I’ve attached an additional article for you to study as well.

In the next lesson, you will learn the final usage of ! and ? in the Swift Programming Language through type castingwhich allows you to convert types that are made up of classes and possibly with structs. ?