Самый простой способ вызвать ошибку / исключение с пользовательским сообщением в Swift 2?
Я хочу сделать что-то в Swift 2, что я привык делать на нескольких других языках: бросить исключение времени выполнения с пользовательским сообщением. Например (в Java):
throw new RuntimeException("A custom message here")
Я понимаю, что я могу бросать типы перечислений, соответствующие протоколу ErrorType, но я не хочу определять перечисления для каждого типа ошибки, которую я бросаю. В идеале, я хотел бы быть в состоянии имитировать примере выше, как можно ближе. Я посмотрел на создание пользовательского класса, который реализует Протокол ErrorType, но я даже не могу понять, что этот протокол требует (см. документация). Идеи?
7 ответов:
самый простой подход, вероятно, определить один custom
enum
только одинcase
что естьString
прилагается к нему:enum MyError: ErrorType { case runtimeError(String) }
или, по состоянию на Swift 4:
enum MyError: Error { case runtimeError(String) }
пример использования будет что-то вроде:
func someFunction() throws { throw MyError.runtimeError("some message") } do { try someFunction() } catch MyError.runtimeError(let errorMessage) { print(errorMessage) }
если вы хотите использовать существующий
Error
типы, самый общий из них будетNSError
, и вы можете сделать заводской метод, чтобы создать и бросить один с пользовательским сообщением.
самый простой способ-сделать
String
соответствуютError
:extension String: Error {}
тогда вы можете просто бросить строку:
throw "Some Error"
чтобы сама строка была
localizedString
ошибки вы можете вместо этого расширитьLocalizedError
:extension String: LocalizedError { public var errorDescription: String? { return self } }
проверьте эту классную версию. Идея заключается в реализации протоколов String и ErrorType и использовании значения rawValue ошибки.
enum UserValidationError: String, Error { case noFirstNameProvided = "Please insert your first name." case noLastNameProvided = "Please insert your last name." case noAgeProvided = "Please insert your age." case noEmailProvided = "Please insert your email." }
использование:
do { try User.define(firstName, lastName: lastName, age: age, email: email, gender: gender, location: location, phone: phone) } catch let error as User.UserValidationError { print(error.rawValue) return }
решение@nick-keets является самым элегантным, но оно сломалось для меня в тестовой цели со следующей ошибкой времени компиляции:
Redundant conformance of 'String' to protocol 'Error'
вот еще один подход:
struct RuntimeError: Error { let message: String init(_ message: String) { self.message = message } public var localizedDescription: String { return message } }
и использовать:
throw RuntimeError("Error message.")
Swift 4:
в:
https://developer.apple.com/documentation/foundation/nserror
Если вы не хотите определять пользовательское исключение, вы можете использовать стандартный объект NSError следующим образом:
import Foundation do { throw NSError(domain: "my error description", code: 42, userInfo: ["ui1":12, "ui2":"val2"] ) } catch let error as NSError { print("Caught NSError: \(error.localizedDescription), \(error.domain), \(error.code)") let uis = error.userInfo print("\tUser info:") for (key,value) in uis { print("\t\tkey=\(key), value=\(value)") } }
принты:
Caught NSError: The operation could not be completed, my error description, 42 User info: key=ui1, value=12 key=ui2, value=val2
Это позволяет вам предоставить пользовательскую строку, а также числовой код и словарь со всеми необходимыми дополнительными данными любого типа.
N. B.: Это было протестировано на OS=Linux (Ubuntu 16.04 LTS).
основываясь на ответе @Nick keets, вот более полный пример:
extension String: Error {}/*Enables you to throw a string*/ extension String: LocalizedError {/*Adds error.localizedDescription to Error instances*/ public var errorDescription: String? { return self } } func test(color:NSColor) throws{ if color == .red { throw "I don't like red" }else if color == .green { throw "I'm not into green" }else { throw "I like all other colors" } } do { try test(color:.green) } catch let error where error.localizedDescription == "I don't like red"{ Swift.print ("Error: \(error)")//"I don't like red" }catch let error { Swift.print ("Other cases: Error: \(error.localizedDescription)")/*I like all other colors*/ }
Первоначально опубликовано в моем блоге swift:http://eon.коды / блог/2017/09/01/метание-простые-ошибки/