エラーの処理

エラーと例外の処理方法について学習します。

Javaエラーは、アプリケーションを構築または実行するときに例外としてスローされます。NoSQLExceptionクラスは、ドライバによってスローされるほとんどの例外のベースとなります。ただし、ドライバからIllegalArgumentExceptionNullPointerExceptionなどの一部のクラスに例外が直接スローされる場合があります。

通常、NoSQL例外インスタンスは、2つの大きなカテゴリに分類されます。

  • 再試行で成功すると予想される例外。

    これらの例外は、RetryableExceptionクラスのインスタンスです。通常、これらの例外は、リソース使用量違反を示します。

  • 再試行後も失敗する例外。

    再試行が不要な例外には、IllegalArgumentExceptionTableNotFoundExceptionなど、構文エラーまたはセマンティック・エラーを示す例外があります。

Pythonエラーは、APIの一部として定義された例外として発生します。これらはすべて、PythonのRuntimeErrorのインスタンスです。ほとんどの例外は、Pythonドライバで発生した例外のベース・クラスであるborneo.NoSQLExceptionのインスタンスです。

例外は、2つの大きなカテゴリに分類されます。1つは、再試行時に成功すると想定して再試行できる例外です。これらはすべてborneo.RetryableExceptionのインスタンスです。たとえば、リソース消費制限を超えた場合に発生するborneo.ThrottlingExceptionのインスタンスです。もう1つは、再度失敗するため、再試行しない例外です。たとえば、borneo.IllegalArgumentExceptionborneo.TableNotFoundExceptionなどです。

関連する制限がないため、borneo.ThrottlingExceptionインスタンスはオンプレミス構成でスローされません。

Go SDKエラーは、APIの一部として定義されたnosqlerr.Error値として報告されます。エラーは、2つの大きなカテゴリに分かれます:
  • 1つは、再試行時に成功すると想定して再試行できるエラーです。これらは、Error.Retryable()メソッド・コールがtrueを返す再試行可能なエラーです。たとえば、nosqlerr.OperationLimitExceedednosqlerr.ReadLimitExceedednosqlerr.WriteLimitExceededなどです。これは、リソース消費制限を超えると発生します。
  • もう1つは、再度失敗するため、再試行しないエラーです。たとえば、nosqlerr.IllegalArgumentErrornosqlerr.TableNotFoundErrorなどです。

NoSQLClientの非同期メソッドは結果としてPromiseを返し、エラーが発生すると、そのエラーでPromiseが拒否されます。NoSQLClientコンストラクタなどの同期メソッドの場合、エラーが例外としてスローされます。SDKで使用されるエラーはすべて、NoSQLErrorのインスタンスまたはそのサブクラスの1つです。エラー・メッセージに加えて、各エラーのerrorCodeプロパティは、ErrorCode列挙で定義された標準エラー・コードの1つに設定されています。errorCodeは、エラーの性質に応じて条件付きロジックを実行する場合に役立つことがあります。

一部のエラー・コードでは、NoSQLErrorの特定のサブクラス(NoSQLArgumentErrorNoSQLProtocolErrorNoSQLTimeoutErrorなど)が定義されています。認可失敗の原因に応じて、NoSQLAuthorizationErrorにいくつかのエラー・コードのいずれかが含まれている場合があります。また、エラーでは、現在のエラーの原因となった基礎となるエラーにcauseプロパティが設定されている場合があります。原因はオプションであり、SDKに含まれないエラーのインスタンスである可能性があります。

さらに、エラー・コードは2つの大きなカテゴリに分割されます:
  • 1つは、操作で再試行時に成功すると想定して再試行できるエラーです。たとえば、ErrorCode.READ_LIMIT_EXCEEDEDおよびErrorCode.WRITE_LIMIT_EXCEEDEDなどです。これらはスロットル・エラー(クラウド環境に関連)であり、ほとんどのネットワーク条件が一時的であるためErrorCode.NETWORK_ERRORでもあります。
  • もう1つは、操作で再度失敗する可能性があるため、再試行しないエラーです。たとえば、ErrorCode.ILLEGAL_ARGUMENT (NoSQLArgumentErrorで表される)、ErrorCode.TABLE_NOT_FOUNDなどです。
NoSQLErrorが再試行可能かどうかを確認するには、retryableプロパティをチェックします。この値は、再試行可能なエラーの場合はtrueに設定され、再試行不可能なエラーの場合はfalseまたは未定義です。

再試行ハンドラ

ドライバは、再試行可能なエラーに対して自動的に操作を再試行します。再試行ハンドラは次を決定します:
  • 操作が再試行されるかどうかと回数。
  • 各再試行までの待機時間。
RetryHandlerは、次の2つのプロパティを持つインタフェースです:
  • 操作に基づいて操作を再試行する必要があるかどうか、これまでに発生した再試行回数、およびエラーが発生した回数を決定するRetryHandler#doRetry。このプロパティは通常関数ですが、自動再試行を無効にするにはブール値のfalseに設定することもできます。
  • RetryHandler#doRetryに指定された情報と同じ情報に基づいて、連続する各再試行の待機時間を決定するRetryHandler#delay。このプロパティは通常関数ですが、一定の遅延のためにミリ秒数に設定することもできます。
NoSQLExceptionは、ドライバによってスローされる多くの例外のベース・クラスとして機能します。ただし、ドライバでは次のような標準の例外タイプが使用される場合があります:
  • ArgumentExceptionおよびそのサブクラス(ArgumentNullExceptionなど)。無効な引数がメソッドに渡されたとき、または無効な構成(コード内またはJSON内)が渡されてNoSQLClientインスタンスが作成されたときにスローされます。
  • NoSQLClientによって発行された操作がタイムアウトすると、TimeoutExceptionがスローされます。タイムアウト例外が多数発生する場合は、NoSQLConfigまたはNoSQLClientメソッドに渡されるオプション引数でタイムアウト値を増やすことを試すことができます。
  • InvalidOperationExceptionは、サービスが無効な状態で操作を実行する場合にスローされます。また、問合せが失敗した場合、その処理がQueryOptions.MaxMemoryMBまたはNoSQLConfig.MaxMemoryMBで指定されたメモリー制限を超えた場合にもスローされることがあります。この場合、対応するメモリー制限を増やすことができます。それ以外の場合は、操作を再試行できます。
  • InvalidCastExceptionおよびOverflowExceptionは、FieldValueのサブクラスを操作し、値を型にキャストしようとしたときに発生する可能性があります。この型では、数値がサポートされないか、または小さい型にキャストされ、算術オーバーフローが発生します。
  • 指定されたCancellationTokenを使用してNoSQLClientのメソッドによって開始された操作の取消しを発行した場合は、OperationCanceledExceptionおよびTaskCanceledException
さらに、例外は次の2つの大きなカテゴリに分類できます:
  • 1つは、操作で再試行時に成功すると想定して再試行できる例外です。通常、これらはRetryableExceptionのサブクラスです。これには、スロットル例外と、リソースが一時的に使用できないその他の例外が含まれています。NoSQLExceptionのその他のサブクラスには、例外が発生した状態に応じて再試行できるものもあります。また、ほとんどのネットワーク状態は一時的であるため、ネットワーク関連のエラーを再試行できます。
  • もう1つは、再試行後も失敗するため、再試行しない例外です。これには、TableNotFoundExceptionTableExistsExceptionなどの例外と、ArgumentExceptionなどの標準例外が含まれています。
NoSQLExceptionの特定のインスタンスが再試行可能かどうかを判断するには、そのIsRetryableプロパティをチェックします。

再試行ハンドラ

デフォルトでは、ドライバは再試行可能な例外をスローした操作を自動的に再試行します(前述を参照)。ドライバは、再試行ハンドラを使用して操作の再試行を制御します。再試行ハンドラは次を決定します:
  • 操作が再試行されるかどうかと回数。
  • 各再試行までの待機時間。
すべての再試行ハンドラは、IRetryHandlerインタフェースを実装します。このインタフェースには2つの方法があり、1つは現在の状態にある操作を再試行する必要があるかどうかを判断し、もう1つは次の再試行までの再試行遅延を判断します。NoSQLClientインスタンスの作成時に、デフォルトの再試行ハンドラを使用するか、独自の再試行ハンドラをNoSQLConfigRetryHandlerプロパティとして設定するかを選択できます。

ノート:

再試行は、操作に割り当てられたタイムアウト期間内にのみ実行され、NoSQLConfig、またはNoSQLClientメソッドに渡されたオプションのタイムアウト・プロパティの1つとして構成されます。タイムアウトに達する前に操作またはその再試行が成功しなかった場合は、TimeoutExceptionがスローされます。
デフォルトでは、ドライバはNoSQLRetryHandlerクラスを使用します。このクラスは、操作タイプ、例外タイプ、および実行された再試行数が事前構成済の最大値に達したかどうかに基づいて再試行を制御します。また、事前に構成されたベース遅延で開始する再試行間の待機には、指数バックオフ遅延も使用されます。最大再試行数、ベース遅延などのプロパティをカスタマイズするには、NoSQLRetryHandlerの独自のインスタンスを作成し、これをNoSQLConfigRetryHandlerプロパティとして設定します。たとえば:
var client = new NoSQLClient(
    new NoSQLConfig
    {
        Region = .....,
        ...............
        RetryHandler = new NoSQLRetryHandler
        {
            MaxRetryAttempts = 20,
            BaseDelay = TimeSpan.FromSeconds(2)
        }
    });
再試行ハンドラを指定しない場合、ドライバはすべてのパラメータのデフォルト値とともにNoSQLRetryHandlerのインスタンスを使用します。または、IRetryHandlerインタフェースを実装して、独自の再試行ハンドラ・クラスを作成することもできます。最後のオプションは、再試行をすべて無効にすることです。これは、かわりにアプリケーション内の操作を再試行する場合に実行できます。再試行を無効にするには、NoSQLConfigRetryHandlerプロパティをNoRetriesに設定します:
var client = new NoSQLClient(
    new NoSQLConfig
    {
        Region = .....,
        ...............
        RetryHandler = NoSQLConfig.NoRetries
    });

リソース制限の処理: リソース制限環境でのプログラミングが困難な場合があります。表にはユーザー指定のスループット制限があり、アプリケーションがそれらの制限を超えるとスロットルされることがあります。つまり、ReadThrottlingExceptionWriteThrottlingExceptionなどのスロットル例外のいずれかで操作が失敗する可能性があります。これは、容量を非常に迅速に使い切って多くのデータを読み取ることができる問合せを使用する場合に最も一般的です。厳密なループで実行されるgetおよびput操作にも発生する可能性があります。

スロットル・エラーが再試行され、カスタムRetryHandlerを使用すると、再試行をより直接制御できる場合もありますが、アプリケーションではスロットル処理の再試行に依存しないでください。これにより、パフォーマンスが低下し、表に使用可能なすべてのスループットを使用できなくなるためです。より適切なアプローチは、アプリケーションのレート制限によって完全にスロットルを回避することです。このコンテキストでは、レート制限とは、操作レートを表の制限に抑えることを意味します。

Spring Dataエラーは、アプリケーションを構築または実行するときに例外としてスローされます。

Spring Data SDKでは、無効なパラメータにIllegalArgumentExceptionが使用され、Java SDKおよびSpring Framework例外が渡されます。Springフレームワークは、一部のクラス(BeansExceptionなど)に対して例外を直接スローします。

exceptionコード・ブロックを追加して、接続設定中の認証の失敗など、スローされる可能性のあるエラーを捕捉できます。また、ERRORおよびDEBUGレベルでのOracle NoSQL Database SDK for Spring Dataでのロギングを有効にできます。詳細は、Spring Data SDK開発者ガイドロギングのアクティブ化を参照してください。