How to cchange the default error when parsing request body failed

Skip to first unread message

Jan 17, 2018, 11:12:58 PM1/17/18
to phoenix-talk
Greetings. I really enjoyed learning and working in Phoenix framework so far. It's proven to be a great tool with amazing code patterns and code readability.
Anyway, regarding my problem. I have an issue regarding default responses. So when JSON body parsing fails, in development, a message is returned with text "Malformed JSON body", however, in production,
only 400 is returned from the server. I'd like to be able to customize this behaviour, and return a custom json. Let's say a json like this: %{message: "Some message when parsing failed"}

I was partially able to achieve this by making a custom Plug, but the actual plug seems very hackish, because in order for it to work I had to disable it in the testing environment.

Here's what I did:

# File /plugs/prepare_parse.ex
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

@doc """
  Overrides the method

def call(conn, opts) do
%{method: method} = conn
# TODO: check for PUT aswell
if method in ["POST"] and not(@env in [:test]) do
= Keyword.get(opts, :json_decoder)
{:ok, body, _conn} = Plug.Conn.read_body(conn)
case decoder.decode(body) do
{:ok, _result} -> conn
{:error, _reason} ->
= %{message: "Malformed JSON in the body"}
|> put_resp_header("content-type", "application/json; charset=utf-8")
|> send_resp(400, Poison.encode!(error))
|> halt

# ...
# 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!
SecuritytrailsApiWeb.Plug.PrepareParse, json_decoder: Poison
# ....

Could there be a better way to achieve something like this that I'm not seeing?
Thanks in advance, happy codding!


Jan 18, 2018, 10:08:57 AM1/18/18
to phoenix-talk
This mailing list is deprecated (I think?), so it's best to ask at overall.  :-)

However, as I recall I 'think' the spec says it should return some kind of formatted error on 400, but you can of course override it to return json instead by returning, well, whatever you want from your 400 error handler in the error_view.ex file.  :-)

Do note that in development the system hooks errors like that to return debuggable errors, but that is disableable on certain routes as well, it's documented someone on the above elixir forum.  :-)
Reply all
Reply to author
0 new messages