defmodule Postgrex.Error do defexception [:message, :postgres, :connection_id, :query] @type t :: %Postgrex.Error{} @metadata [:table, :column, :constraint, :hint] def exception(opts) do postgres = if fields = Keyword.get(opts, :postgres) do code = fields.code fields |> Map.put(:pg_code, code) |> Map.put(:code, Postgrex.ErrorCode.code_to_name(code)) end message = Keyword.get(opts, :message) connection_id = Keyword.get(opts, :connection_id) %Postgrex.Error{postgres: postgres, message: message, connection_id: connection_id} end def message(e) do if map = e.postgres do IO.iodata_to_binary([ map.severity, ?\s, map.pg_code, ?\s, [?(, Atom.to_string(map.code), ?)], ?\s, map.message, build_query(e.query), build_metadata(map), build_detail(map) ]) else e.message end end defp build_query(nil), do: [] defp build_query(query), do: ["\n\n query: ", query] defp build_metadata(map) do metadata = for k <- @metadata, v = map[k], do: "\n #{k}: #{v}" case metadata do [] -> [] _ -> ["\n" | metadata] end end defp build_detail(%{detail: detail}) when is_binary(detail), do: ["\n\n" | detail] defp build_detail(_), do: [] end defmodule Postgrex.QueryError do defexception [:message] end