他の複数の言語で使用していたSwift 2で何かを実行したい:カスタムメッセージでランタイム例外をスローします。例(Javaの場合):
throw new RuntimeException("A custom message here")
ErrorTypeプロトコルに準拠する列挙型をスローできることは理解していますが、スローするエラーのタイプごとに列挙型を定義する必要はありません。理想的には、上記の例を可能な限り模倣できるようにしたいと思います。 ErrorTypeプロトコルを実装するカスタムクラスの作成を検討しましたが、そのプロトコルに必要なものを把握することすらできません( documentation を参照)。アイデア?
最も簡単なアプローチは、おそらくone custom enum
を定義することです。それには、case
が付加されたString
が1つだけあります。
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 }
}
@ 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.")
このクールなバージョンをチェックしてください。考え方は、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
}
スイフト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.codes/blog/2017/09/01/throwing-simple-errors/
追加の拡張、列挙、クラスなどのない最も単純なソリューション:
NSException(name:NSExceptionName(rawValue: "name"), reason:"reason", userInfo:nil).raise()
@ Alexander-Borisenkoの回答は気に入っていますが、ローカライズされた説明はエラーとしてキャッチされても返されませんでした。代わりにLocalizedErrorを使用する必要があるようです:
struct RuntimeError: LocalizedError
{
let message: String
init(_ message: String)
{
self.message = message
}
public var errorDescription: String?
{
return message
}
}
詳細については this answer をご覧ください。
FatalErrorを使用してください:fatalError ("Custom message here")