5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftAdvent Calendar 2024

Day 11

Error の localizedDescription はなぜ上書きされるのか

Last updated at Posted at 2024-12-10

はじめに

Swift で独自の Error を作成する際は localizedDescription を使わずに LocalizedErrorerrorDescription を使いなさいというのはよく聞く話です。この記事はなぜ localizedDescription はダメなのかという話です。

参考

前提

独自のエラーとして下記のように Hoge を実装してみます。

enum Hoge: Error {

    case hoge

    var localizedDescription: String {
        return "hoge"
    }
}

// hogeじゃない
(Hoge.hoge as Error).localizedDescription

(Hoge.hoge as Error).localizedDescription は下記のような値になります。

The operation couldn’t be completed. (Hoge error 0.)

下記のようにしてやると localizedDescription はちゃんと hoge になります。

enum Hoge: Error {

    case hoge
}

extension Hoge: LocalizedError {

    var errorDescription: String? {
        return "hoge"
    }
}

// hoge
(Hoge.hoge as Error).localizedDescription

Hoge.localizedDescription を変更してもダメなのは Error のデフォルト実装があるからそれで上書きされるというのをどこかで見かけてそうなんだと思っていました。
ですが下記のような実装をしても別に上書きされないじゃないかという疑問を持ちました。

protocol Fuga {
    var fuga: String { get }
}

extension Fuga {
    var fuga: String {
        return "fuga"
    }
}

enum Piyo: Fuga {
    case piyo

    var fuga: String {
        return "piyo"
    }
}

// piyo
(Piyo.piyo as Fuga).fuga

なぜ上書きされるのか

ではなぜ localizedDescription は上書きされるのかということなのですがおそらく私の認識が間違っていたのです:flushed:

ErrorlocalizedDescription はプロトコルで定義されているわけではなくおそらく extension なんですね。

Xcode で cmd + control + J で localizedDescription の定義にとぶと下記のようになっていました。

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
extension Error {

    /// Retrieve the localized description for this error.
    public var localizedDescription: String { get }
}

つまり Fuga の例でいうとこんな感じです。

protocol Fuga {}

extension Fuga {
    var fuga: String {
        return "fuga"
    }
}

enum Piyo: Fuga {
    case piyo

    var fuga: String {
        return "piyo"
    }
}

// fuga
(Piyo.piyo as Fuga).fuga

errorDescription の定義にとぶと下記のようにプロトコルで定義されていました。おそらくlocalizedDescription 内で errorDescription を呼ぶような実装になっているものと思われます。

@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
public protocol LocalizedError : Error {

    /// A localized message describing what error occurred.
    var errorDescription: String? { get }

おわりに

今まではそういうものだと思って独自エラーを作る際は errorDescription を使っていましたがこれでスッキリ使えるようになりました:relieved:

5
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?