Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Error Handling in Swift 2.0 Error Handling Handling Errors

Li Lin
PLUS
Li Lin
Courses Plus Student 2,654 Points

How to solve Challenge Task 3 of 3 in Error Handling in Swift 2.0?

How to solve this question?

The question is: "Perfect! We're almost done. Rather than a generic catch clause, let's pattern match on the specific errors so that we can log better error messages. In this task, change the catch statement to include specific error cases. Like before you can just log an error message of your choosing."

And my failed answer is:

enum ParserError: ErrorType {
  case EmptyDictionary
  case InvalidKey
}

struct Parser {
  var data: [String : String?]?

  func parse() throws {
    guard let iData = data else {
      throw ParserError.EmptyDictionary
    }

    if !iData.keys.contains("someKey") {
      throw ParserError.InvalidKey
    }
  }
}

let data: [String : String?]? = ["someKey": nil]

let parser = try Parser(data: data) 

do {
  try parser.parse()
} catch let error{
  switch error{
  case ParserError.EmptyDictionary:
  print("123")
  case ParserError.InvalidKey:
  print("22")
  }
}
error.swift
enum ParserError: ErrorType {
  case EmptyDictionary
  case InvalidKey
}

struct Parser {
  var data: [String : String?]?

  func parse() throws {
    guard let iData = data else {
      throw ParserError.EmptyDictionary
    }

    if !iData.keys.contains("someKey") {
      throw ParserError.InvalidKey
    }
  }
}

let data: [String : String?]? = ["someKey": nil]


do {
    let parser = try Parser(data: data) 
  try parser.parse()
}
catch let error{

    if error == ParserError.EmptyDictionary {
      print("1")
    }
    if error == ParserError.InvalidKey {

    print("1")
    }
  }

 }

3 Answers

Chris McKnight
Chris McKnight
11,045 Points

The challenge wants you to catch a specific type of error and print out a message for that error type. You can do this by specifying the error type in your catch statement

enum ParserError: ErrorType {
    case EmptyDictionary
    case InvalidKey
}

do {
    // Code that could throw
    // ...
}
catch ParserError.EmptyDictionary {
    print("Empty dictionary!")
}
catch ParserError.InvalidKey {
    print("Invalid key!")
}
catch let error as NSError {
    print("Some other error occurred: \(error.localizedDescription)")
}

I am not quite sure what else to do? I tried what Chris did, I am not sure what I am doing wrong?

enum ParserError: ErrorType {
  case EmptyDictionary
  case InvalidKey
}

struct Parser {
  var data: [String : String?]?

  func parse() throws {
    guard let data = data else { throw ParserError.EmptyDictionary 
    } catch  ParserError.EmptyDictionary {
     print("Empty dictionary!")
     }
    guard data.keys.contains("someKey") else { throw ParserError.InvalidKey 
    } catch ParserError.InvalidKey {
    print("Invalid key!")
  }
}

let data: [String : String?]? = ["someKey": nil]
let parser = Parser(data: data)

do {
  try parser.parse()
} catch let error as NSError {
   print ("Some other error occured: \(error.localizedDescription)")
}
Ben Moore
Ben Moore
22,588 Points

Christian, keep in mind this Q&A was for Swift 2. Swift 3 syntax is different. So, below worked for me. [Note: ErrorType in Swift 2 has become Error in Swift 3.] Further, you are to use the do-catch syntax after the Parser struct and below the declaration of "data" and "parser".

enum ParserError: Error {
    case emptyDictionary
    case invalidKey
}

struct Parser {
    var data: [String : String?]?

    func parse() throws {
        guard let dict = data else { throw ParserError.emptyDictionary }
        guard dict.keys.contains("someKey") else { throw ParserError.invalidKey }
}

let data: [String : String?]? = ["someKey": nil]
let parser = Parser(data: data)

do {
    let parsed = try parser.parse()
} catch ParserError.emptyDictionary {
    print("Empty Dictionary!")
} catch ParserError.invalidKey {
    print("Invalid Key!")
}

How do we fix this for Swift 3 in 2017?

I've typed this, but still get an error. Bummer! Make sure you're using a do catch statement to handle propagation of errors. No idea how to fix it. I'm lost. These need to be broken down more in my opinion.

enum ParserError: Error {
    case emptyDictionary
    case invalidKey
}

struct Parser {
    var data: [String : String?]?

    func parse() throws {
        guard let dict = data else { throw ParserError.emptyDictionary }
        guard dict.keys.contains("someKey") else { throw ParserError.invalidKey }
}

let data: [String : String?]? = ["someKey": nil]
let parser = Parser(data: data)

do {
    let parsed = try parser.parse()
} catch ParserError.emptyDictionary {
    print("Empty Dictionary!")
} catch ParserError.invalidKey {
    print("Invalid Key!")
}
Otto linden
Otto linden
5,857 Points

Hello John Hendrix! I hope you got it! But if you are still struggling with the challenge try to remove the let parsed from the do catch statement! 🙂