# File /plugs/prepare_parse.ex
defmodule ApplicationApi.Plug.PrepareParse do
  @moduledoc """
  A Plug used to 'prepareParse'. Phoenix doesn't send a nice error message when the body json
  has invalid attributes. This plug solves just that, if the request body is malformed,
  a more well-formatted message is returned from the server
  """
  import Plug.Conn
  @env Application.get_env(:application_api, :env)
  @doc """
  Overrides the Plug.init/1 method
  """
  def init(opts) do
    opts
  end
  @doc """
  Overrides the Plug.call/2 method
  """
  def call(conn, opts) do
    %{method: method} = conn
    # TODO: check for PUT aswell
    if method in ["POST"] and not(@env in [:test]) do
      decoder = Keyword.get(opts, :json_decoder)
      {:ok, body, _conn} = Plug.Conn.read_body(conn)
      case decoder.decode(body) do
        {:ok, _result} -> conn
        {:error, _reason} ->
          error = %{message: "Malformed JSON in the body"}
          conn
          |> put_resp_header("content-type", "application/json; charset=utf-8")
          |> send_resp(400, Poison.encode!(error))
          |> halt
      end
    else
      conn
    end
  end
end
# ...
# File endpoint.ex
  # HACK: This plug is used to send out a nice error message
  # when a json body contains syntax errors
  # !!IMPORTANT This is NOT BEING tested in the :test environment!
  plug SecuritytrailsApiWeb.Plug.PrepareParse, json_decoder: Poison
# ....