Menu
CoddyTech

Lan truyền lỗi

Thuộc phần Logic và luồng thực thi trong hành trình Swift của Coddy. Bài học 47 trên 56.

Hàm có thể phát sinh lỗi (throwing function) có thể gọi các hàm khác cũng có thể phát sinh lỗi. Lỗi sẽ tự động lan truyền lên cặp do/catch gần nhất, bạn không cần tự ném lại lỗi.

enum AuthError: Error { case badUser, badPass }

func loadUser(_ name: String) throws -> String {
    if name.isEmpty { throw AuthError.badUser }
    return name
}

func login(_ name: String, _ pass: String) throws -> String {
    let u = try loadUser(name)            // chuyển tiếp lỗi
    if pass.count < 4 { throw AuthError.badPass }
    return "hello \(u)"
}

do {
    print(try login("", "abcd"))
} catch AuthError.badUser {
    print("missing user")
} catch AuthError.badPass {
    print("weak password")
}

Đọc từ trên xuống dưới: login gọi loadUser bằng try. Nếu loadUser phát sinh lỗi, lỗi sẽ bỏ qua phần thân của login và chuyển đến catch bên ngoài. Bạn viết từng bước sao cho lỗi xảy ra sớm, rồi để bên gọi quyết định cách xử lý.

challenge icon

Thử thách

Trung bình

Xây dựng một quy trình xử lý nhỏ gồm hai bước có thể ném lỗi.

Định nghĩa StepError: Error với hai trường hợp: negative, tooBig.

Định nghĩa parseSafe(_ s: String) throws -> Int: ném .negative khi số nguyên được phân tích nhỏ hơn 0, nếu không thì trả về số đó. (Giả sử đầu vào phân tích được, bạn đã xử lý việc đó ở nơi khác.)

Định nghĩa capStrict(_ n: Int) throws -> Int: ném .tooBig khi n > 100, nếu không thì trả về n.

Định nghĩa processStep(_ s: String) throws -> Int để gọi parseSafe rồi gọi capStrict, cho phép mọi lỗi lan truyền lên.

Đọc một dòng đầu vào duy nhất: một danh sách chuỗi (string) được phân tách bằng dấu phẩy. Với mỗi chuỗi, gọi processStep trong khối do/catch và in ra một dòng:

  • ok: <n> nếu thành công
  • negative khi parseSafe ném lỗi
  • too big khi capStrict ném lỗi

Với đầu vào 10,-1,200,42, đầu ra là:

ok: 10
negative
too big
ok: 42

Tự làm thử

let parts = readLine()!.components(separatedBy: ",")

// TODO: khai báo enum StepError; parseSafe; capStrict; processStep;
// Với mỗi phần, dùng do/try để gọi processStep, dùng catch cho từng nhánh, rồi in ra
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng thực thi

Tự luyện tập: Playground Swift