LoginSignup
3

More than 3 years have passed since last update.

posted at

updated at

Androidアプリでのエラー処理について

この記事はCAM Advent Calendar 2019 の24日目の記事です。:golf:
昨日は@takehziさんのトランザクションとロックと二重課金でした。

:warning: エラー処理って何?

Androidに限らず、クライアントアプリ全般的に言えることですが、よく「エラーが発生しました。もう一度やり直してください。」みたいなポップアップを見かけると思うのですが、それを表示するまでに行う処理のことをここでのエラー処理とします。

ここで紹介するのはあくまで一つの手法です。

:thinking: やること

1. エラーを受け取る
2. 受け取ったエラーに対してそれぞれ処理を分ける

... 以上

と言っても、これだけだとさっぱりなので順を追って説明できればと思います。

1. エラーを受け取る

この受け取り方はそれぞれだと思いますが、今回はtry-catchExceptionなりを受け取る想定で書いていきます。


try {
...
} catch(e: Exception) {
// ここで受け取る
}

このときcatchには色んな種類のエラーがくることが想定されます。
何でもいいからエラーだったら「エラーが発生しました」というポップアップを出して終わりであればここで受け取って終わりですが、今回はエラーの種類によって出しわけたいのでこれでは不十分です。

それを行うにはどういった種類のエラーなのかを判断するための情報が必要になります。

2. 受け取ったエラーに対してそれぞれ処理を分けるに行く前に準備をしましょう。

アプリ内で扱うエラーのクラスを作る

catchで受け取れるためにExceptionクラスを継承したクラスを用意します。

abstract class CustomException(errorMessage: String): Exception(errorMessage)
abstract class ApiException(errorMessage: String): CustomException(errorMessage)
abstract class LocalException(errorMessage: String): CustomException(errorMessage)
...

エラーを種別にするために上記のようなクラスを作って継承関係でわけてもいいですが、今回はKotlinのsealed classを使って分けてみます。

sealed class CustomException(errorMessage: String) : Exception(errorMessage) {
    sealed class ApiException(errorMessage: String) : CustomException(errorMessage) {
        data class NetworkException(val errorMessage: String): ApiException(errorMessage)
        ...
    }
    sealed class LocalException(errorMessage: String) : CustomException(errorMessage) {
        ...
    }
}

以上でエラークラスの準備は終わりです。

2. 受け取ったエラーに対してそれぞれ処理を分ける

受け取ったエラーに対してどのような処理を行うかを決定していきます。


try {
...
} catch(e: Exception) {
    when(e) {
        is CustomException.ApiException.NetworkException -> { 
                    // やりたい処理
           }
        ...
        else -> {...}
    }
}

とりあえずはここでやりたいことは終わりなのですが、このような書き方をすると全画面でエラーの分岐処理を書くことになります。
なのでエラーを処理する専用クラスを設けてそちらに処理をまとめると管理しやすくなります。

/**
 * 例外を受け取って処理を分ける
 */
fun onErrorReceived(e: Exception) {
    when(e) {
        is CustomException.ApiException.NetworkException -> { 
                    // やりたい処理
           }
        ...
        else -> {...}
    }
}

メソッドに返却値を設けてEnumなどを返してもいいですが、RxJavaLiveDataを使っているのであればそちらを使ってView側へ通知を流す形にするとスッキリ書けます。

まとめ :notebook:

Exceptionクラスを継承したクラスを自作してのエラーハンドリングを紹介しました。
久しぶりの技術ブログだったので何を書こうか迷った挙げ句、基本的な内容になってしまいましたが、これからは定期的に書いていければと思っています。

:santa: 明日は@kidoyunaさんの記事が公開予定です。ぜひそちらもご覧ください。:eye:

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
What you can do with signing up
3