rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

kotlin Resultクラスによる例外処理

2021 Aug. 19.

例外を補足するrunCatching { }の結果はResult<T>オブジェクトに格納される。
Resultのメソッドで例外発生有無を判定したり、処理の返り値としてResult<T>に格納されたTクラスのインスタンスを取得したりできる。

参考ページ
【Kotlin】try-catch がやりにくければ runCatching を使ってみよう! - Qiita


get系関数はいずれもブロックの実行に成功したときにはその結果の返値(Result<T>のTのインスタンス)を返す。
それぞれのget系関数で失敗したときの動作が異なる。
getOrNull( )

ブロック内で例外がスローされた場合は null が返る

getOrThrow( )

ブロック内でスローされた例外をそのままスローする

getOrDefault( )

指定されたデフォルト値を返す

getOrElse( )

指定された処理を実行する


isFailure

例外が発生していたらTRUEを返す

SMBサーバーへの接続での利用例

例1
(やっていること)
コルーチンブロック内のrunCatching { }内でSMBサーバーに接続する。
runCatching { }の結果を変数smbConnectionに入れる。
smbConnectionにはResult<T>型が入る。この例の場合は、Result<SmbFile>型。
smbConnection.getOrElse()で、例外が発生していなければResult<SmbFile>に入っているSmbFile型のインスタンスを取得でき、例外が発生していればthrow Exception("connectSmb failed.")が実行される。

    private suspend fun connectSmb(user: String, password: String, domain: String, smbroot: String): SmbFile {
        return withContext(Dispatchers.IO) {
            val prop = Properties()
            prop.setProperty("jcifs.smb.client.minVersion", "SMB202")
            prop.setProperty("jcifs.smb.client.maxVersion", "SMB300")

            val smbConnection = runCatching {
                val bc = BaseContext(PropertyConfiguration(prop))
                val creds = NtlmPasswordAuthentication(bc, domain, user, password)
                val auth: CIFSContext = bc.withCredentials(creds)
                SmbFile(smbroot, auth)
            }
            smbConnection.getOrElse {
                throw Exception("connectSmb failed.")
            }
        }
    }


例2
return@withContext runCatching { } .getOrElse { }で結果を返す

    private suspend fun connectSmb(user: String, password: String, domain: String, smbroot: String): SmbFile {
        return withContext(Dispatchers.IO) {
            val prop = Properties()
            prop.setProperty("jcifs.smb.client.minVersion", "SMB202")
            prop.setProperty("jcifs.smb.client.maxVersion", "SMB300")

            return@withContext runCatching {
                val bc = BaseContext(PropertyConfiguration(prop))
                val creds = NtlmPasswordAuthentication(bc, domain, user, password)
                val auth: CIFSContext = bc.withCredentials(creds)
                SmbFile(smbroot, auth)
            }
            .getOrElse {
                throw Exception("connectSmb failed.")
            }

        }
    }