Có hai điểm quan trọng đối với mô hình xử lý lỗi Swift 2: tính toàn diện và khả năng phục hồi. Cùng nhau, họ thực hiện theo do
/ catch
tuyên bố của bạn cần nắm bắt mọi lỗi có thể xảy ra, không chỉ những lỗi bạn biết bạn có thể ném.
Lưu ý rằng bạn không khai báo loại lỗi nào mà hàm có thể đưa ra, chỉ cho dù nó có ném lỗi hay không. Đó là một loại vấn đề không có một không hai: khi ai đó xác định chức năng cho người khác (bao gồm cả bản thân tương lai của bạn) sử dụng, bạn không muốn làm cho mọi khách hàng của chức năng của mình thích ứng với mọi thay đổi trong quá trình thực hiện của bạn chức năng, bao gồm những lỗi nó có thể ném. Bạn muốn mã gọi chức năng của bạn có khả năng phục hồi với sự thay đổi đó.
Vì chức năng của bạn không thể nói loại lỗi nào sẽ ném (hoặc có thể ném trong tương lai), nên các catch
khối bắt lỗi đó không biết loại lỗi nào có thể gây ra. Vì vậy, ngoài việc xử lý các loại lỗi bạn biết, bạn cần xử lý các loại lỗi bạn không sử dụng bằng một catch
câu lệnh phổ quát - theo cách đó nếu chức năng của bạn thay đổi tập hợp các lỗi mà nó gây ra trong tương lai, người gọi vẫn sẽ bắt lỗi lỗi.
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch SandwichError.NotMe {
print("Not me error")
} catch SandwichError.DoItYourself {
print("do it error")
} catch let error {
print(error.localizedDescription)
}
Nhưng đừng dừng lại ở đó. Hãy suy nghĩ về ý tưởng kiên cường này thêm một số. Cách bạn thiết kế bánh sandwich của mình, bạn phải mô tả lỗi ở mọi nơi bạn sử dụng chúng. Điều đó có nghĩa là bất cứ khi nào bạn thay đổi tập hợp các trường hợp lỗi, bạn phải thay đổi mọi nơi sử dụng chúng ... không thú vị lắm.
Ý tưởng đằng sau việc xác định các loại lỗi của riêng bạn là để cho phép bạn tập trung hóa những thứ như thế. Bạn có thể xác định một description
phương pháp cho các lỗi của mình:
extension SandwichError: CustomStringConvertible {
var description: String {
switch self {
case NotMe: return "Not me error"
case DoItYourself: return "Try sudo"
}
}
}
Và sau đó, mã xử lý lỗi của bạn có thể yêu cầu loại lỗi của bạn mô tả chính nó - bây giờ mọi nơi bạn xử lý lỗi đều có thể sử dụng cùng một mã và xử lý các trường hợp lỗi có thể xảy ra trong tương lai.
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch let error as SandwichError {
print(error.description)
} catch {
print("i dunno")
}
Điều này cũng mở đường cho các loại lỗi (hoặc tiện ích mở rộng trên chúng) hỗ trợ các cách báo cáo lỗi khác - ví dụ: bạn có thể có tiện ích mở rộng về loại lỗi của mình để biết cách trình bày UIAlertController
báo cáo lỗi cho người dùng iOS.