Overview
タイトルの通りです。 DynamoDB へのリクエストにおいて Context Cancel エラーになった場合にその Context Cancel をハンドリングします。
DynamoDB 側でのエラーハンドリング
DynamoDB へのリクエストにおいて Context Cancel の実装は https://pkg.go.dev/github.com/aws/smithy-go#CanceledError.CanceledError でされています。
CanceledError returns true to satisfy interfaces checking for canceled errors.
Godoc にも canceled の時に返されると記載されているので、最終的にこの Context cancel エラーをハンドリングしたい箇所で取り出してハンドリングできれば良さそうです。
コードを追っかけていきます
実際に SDK のコードを追っていきます。
Query() 関数をサンプルとして見ていきます。
Query
関数の内部で invokeOperation を 呼び出していて、この invokeOperation
の中での smithy-go 内部にある middleware.DecorateHandler
の Handle メソッドを Call します。このい Handle
メソッドで発生してエラーは invokeOperation
メソッドでは OperationError として返されます。 Handle
メソッドのエラーが OperationError に入れられて返されることになります。
次にこの Handle
の実装以下を追っていきます。
この Handle
メソッド内部で Middleware
に実装された HandleMiddleware を Call しており、これは BuildStep
に実装されたHandleMiddleware を Callします。
さらに、この実装の内部で buildWrapHandler
が実装してる HandleBuild を Call しており、HandleBuild
内部の buildWrapHandler.Handler
に実装されている Handle メソッドで実際に AWS 本体と通信してる HTTP Client に実装された Handle メソッド の内部で、smithy-go.CanceledError
を返してる箇所があります。
これがエラーを返してる本体です。
実際のエラーハンドリング方法
いくつかやり方があると思います。一番単純なのは Dynamo から返されたエラーの文字列の中に context canceled
が含まれていればヨシ!とする方法です。
ただし、エラーの文字列一致はそれじゃないと対応できない場合を除いて極力採用するべき方針ではありません。
できることであれば Go のエラー方をそのまま使って errors.Is
でハンドリングしたいです。Go のエラーはエラーが返される過程で fmt で wrap されている or 独自エラーで wrap されている限り errors.Is
でエラーの判別をすることが可能です。
※ どこかでエラーを書き換えてしまってる場合、正常にハンドリングできません。
実際にエラーが取り出せるかをキャストでやって見ました -> https://play.golang.org/p/KPPzJgqspIk
これは trueが返ってきました(つまり context canceled が発火したということ)
次に errors.Is
でハンドリングできるかやって見ました -> https://play.golang.org/p/vT4anMduCL7
※ 余計なエラーで書き換えてない場合のみ。途中に errors.New
があったりして元々のエラーからさらに書き換えていると Is で取り出すことはできません。
まとめ
エラーハンドリング、、されどエラーハンドリング。
安易に文字列比較に逃げることなく、Error が定義されてるはずだ、と見通しを立てて実装するって大事だなと思いました。
追記
AWS のリクエストを送信する invokeOperation
メソッドが返す smithy.OperationError
は Unwrap
を 実装してる ので、AWS 内では発生した何かしらの OperationError
は errors.Is
で Unwrap
して取り出すのが良いです。
OperationError
は operation error {$ResourceName}: {$OperationName}, https response error...
という文字列で返ってくるエラーのことです。