2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Mariaexの接続時エラーをがんばってハンドリングする

2
Last updated at Posted at 2016-01-03

ElixirのMariaDB/MySQLドライバでmariaexというのがあります。

使い方は以下のような感じで難しくはないです。

{:ok, p} = Mariaex.Connection.start_link(username: "ecto", database: "ecto_test")
Mariaex.Connection.query(p, "CREATE TABLE test1 (id serial, title text)")

で、稼働時のエラー、たとえばSQLのSyntaxErrorやらDB落ちてるとかはいくらでもリトライなり、プロセスの再起動なりをすればいいんですが、DB名を間違えた…とかだと致命的なので即刻終了する必要があります。

IO.inspect Mariaex.Connection.start_link(database: "testx")

スクリーンショット 2016-01-04 1.04.27.png

case文で{:error, pid}をハンドルすればいいかと思ったら、コンソールにエラーメッセージが。
まあエラーはいたり死んだりするのはいいんですけど、適切にエラーをハンドリングして整形したメッセージ出して終了したいんですよ。(loggerのフォーマットをいじるのも全体に影響するし、なんか対処が違う気が)

じゃあProcess.monitor(pid)してメッセージを捕まえようとしてもstart_linkで死ぬのでどうにもこうにも。

GenServerでラップしたり、非同期にしたりといろいろやったんですが、最終的に以下のように。

# 要mariaex ~> 0.6.1

# 失敗時
Agent.start(fn ->
  Mariaex.Connection.start_link(database: "testx", sync_connect: true)
end)
# => {:error,
#    %Mariaex.Error{mariadb: %{code: 1044,
#       message: "Access denied for user ''@'localhost' to database 'testx'"},
#     message: nil}}

# 成功時
{:ok, agent} = Agent.start(fn ->
  Mariaex.Connection.start_link(database: "test", sync_connect: true)
end)

{:ok, mysql} = Agent.get(agent, fn mysql -> mysql end)
Agent.stop(agent) # あるいはAgentにコネクション入れっぱなしにして使い続ける?

IO.inspect Mariaex.Connection.query(mysql, "SHOW VARIABLES")

その場でエラーハンドリングできるし、変なところにもメッセージを投げない!

…しかし無理矢理感があるような…

識者の方がいたらぜひご教授いただきたいです。

(なんとなーくstart_linkでfailする設計がよくない気もするんですが、mariaexの場合、start_linkと接続処理が明示的に分かれてない。sync_connect: falseとやっても結局タイミングがあわないとpidをモニタリングする前に死ぬし)

2
2
0

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
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?