elixir-maru / maru

Elixir RESTful Framework
https://maru.readme.io
BSD 3-Clause "New" or "Revised" License
1.32k stars 85 forks source link

What's the proper way to return a 400? #35

Open dblock opened 8 years ago

dblock commented 8 years ago
      if System.get_env("SLACK_SLASH_COMMAND_TOKEN") != params[:token] do
        conn
          |> put_status(403)
          |> text("Unauthorized")

        raise("Unauthorized") <<---- this seems wrong
      end

What's the equivalent of grape's error! that lets me do

      # check that token matches, that the POST comes from our slack integration
      if System.get_env("SLACK_SLASH_COMMAND_TOKEN") != params[:token] do
        error! 403, "Unauthorized"
      end

      # this code is not excuted
falood commented 8 years ago

There's not a function or macro equal to grape's error! yet. error!/2 is an unhygienic macro, I must wrap it like this:

      if System.get_env("SLACK_SLASH_COMMAND_TOKEN") != params[:token] do
        error!(conn, 403, "Unauthorized")
      end

But I don't think Unauthorized is friendly to client, may be {"status": "error", "message": "Unauthorized"} is better. So just like what I said #34, I think we should do it like this:

    if System.get_env("SLACK_SLASH_COMMAND_TOKEN") != params[:token] do
      raise "Unauthorized"
    end

    rescue_from RuntimeError, as: e do
      conn |> put_status(403) |> json(%{status: :error, message: e.message})
    end

How about this?

falood commented 8 years ago

@dblock I updated my comment.

I see! I used to think error! raised an exception, and it seems to make response directly! It's necessary to make an equivalent of error!!

dblock commented 8 years ago

It does both. There's currently no way to halt a response in Maru (or at least I didn't find how to do that).

falood commented 8 years ago

Because elixir function can't be halted except raise an exception, there's nothing like return. So I must raise a special exception and do a special process.

falood commented 7 years ago

Hi @dblock , are you still using elixir? I tried to make error!, I success to make it raise a special exception, then catch and process it, the flow like this:

try do
  ... MY CODE WITHIN ENDPOINT
  error!("Error Message", 400)
  ... MY OTHER CODE WITHIN ENDPOINT
rescue
  e in MySpecialException ->
    MyErrorHandler.format(conn, e)
end

It works but I don't think it make sense for elixir because it break a function.

It seems that, I tried to halt a response but I don't think elixir should provide such method after I found it.

As the same as #34 , I think the only things I can do are making name of exceptions idiomatic and provide a default error handler.

dblock commented 7 years ago

@falood Yes, we're using it in https://github.com/artsy/aprb, cc: @ashkan18