I want to return a specific error response (HTTP 503 with a custom message) when Ecto (or postgrex?) encounters a database query timeout.
When a timeout occurs, the exception thrown looks like this:
** (DBConnection.ConnectionError) tcp recv: closed
(ecto) lib/ecto/adapters/postgres/connection.ex:86: Ecto.Adapters.Postgres.Connection.prepare_execute/5
(ecto) lib/ecto/adapters/sql.ex:243: Ecto.Adapters.SQL.sql_call/6
(ecto) lib/ecto/adapters/sql.ex:431: Ecto.Adapters.SQL.execute_and_cache/7
(ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5
(ecto) lib/ecto/repo/queryable.ex:35: Ecto.Repo.Queryable.all/4
(stdlib) timer.erl:166: :timer.tc/1
I defined an implementation for the Plug.Exception protocol to map DBConnection.ConnectionError to a status 503 when the exception message is "tcp recv: closed", which seems to work.
defimpl Plug.Exception, for: DBConnection.ConnectionError do
def status(exception) do
if exception.message == "tcp recv: closed" do
503
else
500
end
end
end
However, my worry is that the DBConnection.ConnectionError exception along with "tcp recv: closed" is too general for me to assume that a DB timeout occurred. What if the closed connection was caused by something else, like a network failure?
Is there a more specific way to detect when a DB query timeout has occured?