Самый простой способ бросить ошибку/исключение с помощью специального сообщения в Swift 2?
Я хочу сделать что-то в Swift 2, что я привык делать на нескольких других языках: бросить исключение из среды выполнения с помощью специального сообщения. Например (на Java):
throw new RuntimeException("A custom message here")
Я понимаю, что могу перечислить типы перечислений, соответствующие протоколу ErrorType, но я не хочу определять перечисления для каждого типа ошибок, которые я бросаю. В идеале я хотел бы как можно лучше подражать приведенному выше примеру. Я изучил создание настраиваемого класса, который реализует протокол ErrorType, но я не могу даже понять, что требуется для этого протокола (см. documentation). Идеи?
Ответы
Ответ 1
Самый простой подход, вероятно, состоит в том, чтобы определить одно пользовательское 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
, и вы можете создать фабричный метод, чтобы создать и выдать его с пользовательским сообщением.
Ответ 2
Самый простой способ: String
соответствовать Error
:
extension String: Error {}
Затем вы можете просто выбросить строку:
throw "Some Error"
Чтобы сама строка была localizedString
ошибки, вы можете расширить LocalizedError
:
extension String: LocalizedError {
public var errorDescription: String? { return self }
}
Ответ 3
@решение 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.")
Ответ 4
Проверьте эту классную версию. Идея состоит в том, чтобы реализовать оба протокола 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
}
Ответ 5
Свифт 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
Это позволяет вам предоставить пользовательскую строку, а также числовой код и словарь со всеми необходимыми дополнительными данными любого типа.
Примечание: это было протестировано на OS = Linux (Ubuntu 16.04 LTS).
Ответ 6
На основе ответа @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*/
}
Первоначально опубликовано в моем быстром блоге: http://eon.codes/blog/2017/09/01/throwing-simple-errors/
Ответ 7
Самое простое решение без дополнительных расширений, перечислений, классов и т. Д.:
NSException(name:NSExceptionName(rawValue: "name"), reason:"reason", userInfo:nil).raise()
Ответ 8
Мне нравится ответ @Alexander-Borisenko, но локализованное описание не было возвращено при обнаружении ошибки. Кажется, что вам нужно использовать LocalizedError вместо:
struct RuntimeError: LocalizedError
{
let message: String
init(_ message: String)
{
self.message = message
}
public var errorDescription: String?
{
return message
}
}
Смотрите этот ответ для более подробной информации.
Ответ 9
Просто используйте fatalError: fatalError ("Custom message here")