1

私は少し検索しましたが、何も見つかりませんでした.このサイトの質問でさえありません.Swift 2がJavaのようなマルチキャッチブロックをサポートしているかどうか疑問に思っています.

Java の例:

try {
    someMethod(); // throws ExceptionOne, ExceptionTwo
} catch(ExceptionOne | ExceptionTwo e) {
    handleMyException();
} catch(Exception e2) {
    handleOtherExceptions();
}

Swift では、同様のソリューションを実装できませんでした。This questionは、1つの列挙型のさまざまなエラーを処理するための優れた方法を説明してErrorTypeいますが、HTTP応答からのメッセージでエラーが初期化されるため、私の要件は異なるようです. これは私の列挙型です:

enum HTTPError: ErrorType {
    case BAD_REQUEST(message: String)
    case UNAUTHORIZED(message: String)
    case NOT_FOUND
    case INTERNAL_SERVER_ERROR(message: String)
    case NOT_IMPLEMENTED(message: String)

    static func getErrorForStatusCode(statusCode: Int, message: String? = nil) -> HTTPError {
        switch statusCode {
        case 400:
            return HTTPError.BAD_REQUEST(message: message!)
        case 401:
            return HTTPError.UNAUTHORIZED(message: message!)
        case 404:
            return HTTPError.NOT_FOUND
        case 500:
            return HTTPError.INTERNAL_SERVER_ERROR(message: message!)
        case 501:
            return HTTPError.NOT_IMPLEMENTED(message: message!)
        default:
            return HTTPError.INTERNAL_SERVER_ERROR(message: message!)
        }
    }
}

その列挙型のエラーをスローしたいときは、次のようなコードを使用します。

func someMethod() throws {
    ...
    HTTPError.getErrorForStatusCode(400, message: "Field X missing") // Actual values coming from HTTP-response
    ...
}

ここで、呼び出し元のメソッドで、列挙型のすべてのエラーを個別にキャッチする必要がありますが、すべて同じようにしたいのですが ( を除きますが、NOT_FOUNDここでは問題ありません)。

try {
    someMethod() // throws
} catch HTTPError.BAD_REQUEST(let message) {
    // display 'message' to user
} catch HTTPError.UNAUTHORIZED(let message) {
    // display 'message' to user
} catch HTTPError.INTERNAL_SERVER_ERROR(let message) {
    // display 'message' to user
}
...

Swift 2 には本当にマルチキャッチが含まれていないのですか? または、私の問題を解決するのに役立つ別の解決策はありますか?

編集:私の希望する動作がはっきりしていないようです: タイプ HTTPError (HTTPError.NOT_FOUND を除く) のエラーを同じ方法で処理したいので、マルチキャッチを求めています。

認識していないすべてのエラー (タイムアウト、nil-access など) をカバーするために、一般的な catch-block を引き続き実装しますが、バックエンド メッセージに伴うエラーは特別に処理する必要があります。

ありがとう、チャッキー

4

3 に答える 3

1

Swift 2 はマルチキャッチをサポートしています

ドキュメントから

句が処理できるエラーを示すために、catch の後にパターンを記述します。catch 句にパターンがない場合、句はすべてのエラーに一致し、エラーを という名前のローカル定数にバインドしますerror

したがって、そのerror定数を取得してswitchステートメントを使用します。

do {
  try someMethod() // throws
} catch let error as HTTPError {
  switch error  {
  case .NOT_FOUND:
    print("not found")
  case let message: // handle all errors with a message
    print(message)
  }
}

またはcatchパターンで

do {
  try someMethod() // throws
} catch HTTPError.NOT_FOUND {
    print("not found")
} catch let message {
    print(message)
}

他のすべてのケースにはメッセージがあるため、これも網羅的です。

それとは別に、開発者は、列挙型のケースの数を正確に知っているはずなので、それらを確実に処理できます。

編集:

別の解決策は、associatedValueプロパティをenum

  var associatedValue : String {
    switch self {
    case BAD_REQUEST(let value) : return value
    case UNAUTHORIZED(let value) : return value
    case INTERNAL_SERVER_ERROR(let value) : return value
    case NOT_IMPLEMENTED(let value) : return value
    default: return ""
    }
  }

このスイッチステートメントを使用します

do {
  try someMethod() // throws
} catch HTTPError.NOT_FOUND {
  print("not found")
} catch let error as HTTPError {
  print(error.associatedValue)
}
于 2016-02-14T21:14:11.073 に答える
0
enum Error: ErrorType {
    case E1
    case E2
    case E3
}

func foo(e: Error) throws {
    throw e
}

do {
    try foo(Error.E2)
} catch Error.E1 {
    print(Error.E1) // only Error.E1
} catch {
    print("error: ", error) // all other errors
}
/*
error:  E2
*/
于 2016-02-14T21:13:13.053 に答える
0

マルチパターン キャッチが Swift 5.3 でサポートされるようになりました。提案の詳細を確認して ください。

于 2020-08-28T14:38:58.500 に答える