RailsでActiveRecord::Base.connection.select_allを実行した時、SQLに誤りがあればActiveRecord::StatementInvalidの例外が発生します。
例えば存在しないSQLでfromが抜けている場合は以下の様な例外となります。
select_all("select * hoge;") # fromが抜けている
PG::SyntaxError: ERROR: syntax error at or near \"hoge\"\nLINE 1: select * hoge;\n ^\n: select * hoge;
SyntaxError
や syntax error at or near "hoge"
の情報を取得したかったので、正規表現で無理やり取得してみました。
/PG::(.*):\sERROR:\s(.*)/
- 1つめの
(.*)
にて、エラー種別を取得 - 2つめの
(.*)
にて、エラー詳細を取得
err_type = e.message[/PG::(.*):\sERROR:(.*)/, 1]
# => "SyntaxError"
err_msg = e.message[/PG::(.*):\sERROR:(.*)/, 2]
# => " syntax error at or near \"hoge\""
その後エラーの種類によってハンドリングするような処理を作ってみました。
begin
result = connection.select_all(sql)
rescue ActiveRecord::StatementInvalid => e
reg_pattern = /PG::(.*):\sERROR:\s(.*)/
err_type = e.message[reg_pattern, 1]
err_msg = e.message[reg_pattern, 2]
case err_type
when "UndefinedColumn"
raise "カラム名が定義されていません."
when "UndefinedTable"
raise "テーブル名が正しくありません."
when "SyntaxError"
raise "SQLの構文に誤りがあります.\n(#{err_msg})"
else
raise "SQLの構文に誤りがあります.\n(#{err_msg})"
end
多分もっといいほうがあると思いますが、参考になればと思います。