Rails + Dynamoid(DynamoDB) で、存在しない Primary Key へアクセスした場合の回避方法

2023/12/27に公開

Ruby on RailsDynamoDBActiveRecord のように扱える Dynamoid を使用しています。
存在しないパーティションキーを使用して、find などを行った場合、Dynamoid::Errors::RecordNotFound が発生します(仕様)。
その場合の処理方法を備忘録として残します。

要約

  • begin-rescueDynamoid::Errors::RecordNotFound を拾う
  • raise_error option を false に設定する

begin rescue で Dynamoid::Errors::RecordNotFound を拾う

Dynamoid::Errors::RecordNotFoundbegin-rescue で拾います。
rescue に入ったときにエラーコードなりでキーが存在しないことを返せばいいんじゃないかなと思います。

サンプルコード
class SampleController < ActionController::Base
  def show
    meta = {
      exist: true
    }
    begin
      r = SampleTable.find("pk-1", range_key: "sk-1")
    rescue Dynamoid::Errors::RecordNotFound
      r = SampleTable.new
      meta[:exist] = false
    end
    # begin と end でそれぞれ render してもいいかも
    render json: r,
           root: 'data',
           adapter: :json,
           meta: meta
  end
end

raise_error option に false を設定する

別の方法として、find を実行する際に raise_error オプションを設定する方法があります。
raise_errorfalse に設定することで、Dynamoid::Errors::RecordNotFound` の発生を抑制することができます。

r = SampleTable.find("pk-1", range_key: "sk-1", raise_error: false)

今後試したいこと

エラーとエラーメッセージを定数で紐づけて管理したり、基盤のコントローラーで管理したりする方法も試したい。

https://tech.timee.co.jp/entry/2020/08/11/182724

参考

https://github.com/Dynamoid/dynamoid
https://www.rubydoc.info/gems/dynamoid/3.9.0
https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#begin
https://www.rubydoc.info/gems/dynamoid/Dynamoid%2FFinders%2FClassMethods:find

Discussion