blog.bouzuya.net

2025-09-29 Error 型の名前

Error 型を定義するときに Error という名前に統一して mod を区切っておき、使うときにはフルパスで指定していた。

mod user {
    #[derive(Debug, thiserror::Error)]
    #[error("user error")]
    pub struct Error(#[source] Box<dyn std::error::Error + Send + Sync>);

    // ...
}

mod role {
    #[derive(Debug, thiserror::Error)]
    #[error("role error")]
    pub struct Error(#[source] Box<dyn std::error::Error + Send + Sync>);

    // ...
}

ところが、この運用だと pub mod xxx のように mod を pub にする必要が出てくる。 mod を export することで re-export されている型が不明瞭になるし、複数のパスで使用できるようになってしまう。

pub mod user;

pub use self::user::User;
// self::User も self::user::User の複数のルートで使用できてしまう

また mod ごと re-export するよりも必要な型のみを re-export するほうが、 re-export する mod の時点で、どこまで公開にするのかが把握しやすくなる。

// user::Error の形で使用するため mod を pub にしないといけないが、
// mod が pub になっているため、 user mod の中身を見ないと何が export されているか、この位置から判断できない
pub mod user;

結局、名前が長くなってしまっても UserError のような長い名前にしておくか、名前を変えて UserError のような名前で re-export するのが良いかもと考えている。


今日のコミット。