mirror of
https://github.com/ash-project/ash_phoenix.git
synced 2024-09-17 05:42:49 +12:00
feat: add custom HTTP status codes for specific types of errors that can be thrown (#62)
This commit is contained in:
parent
3ec3a3941c
commit
ac3e2dc9ac
2 changed files with 54 additions and 0 deletions
27
lib/ash_phoenix/plug/exception.ex
Normal file
27
lib/ash_phoenix/plug/exception.ex
Normal file
|
@ -0,0 +1,27 @@
|
|||
errors = [
|
||||
{Ash.Error.Invalid.InvalidPrimaryKey, 400},
|
||||
{Ash.Error.Query.InvalidArgument, 400},
|
||||
{Ash.Error.Query.InvalidFilterValue, 400},
|
||||
{Ash.Error.Query.NotFound, 404}
|
||||
]
|
||||
|
||||
# Individual errors can have their own status codes that will propagate to the top-level
|
||||
# wrapper error
|
||||
for {module, status_code} <- errors do
|
||||
defimpl Plug.Exception, for: module do
|
||||
def status(_exception), do: unquote(status_code)
|
||||
def actions(_exception), do: []
|
||||
end
|
||||
end
|
||||
|
||||
# Top-level Ash errors will use the highest status code of all of the wrapped child errors
|
||||
defimpl Plug.Exception,
|
||||
for: [Ash.Error.Invalid, Ash.Error.Forbidden, Ash.Error.Framework, Ash.Error.Unknown] do
|
||||
def status(%{errors: errors} = _exception) do
|
||||
errors
|
||||
|> Enum.map(&Plug.Exception.status/1)
|
||||
|> Enum.max()
|
||||
end
|
||||
|
||||
def actions(_exception), do: []
|
||||
end
|
27
test/plug_test.exs
Normal file
27
test/plug_test.exs
Normal file
|
@ -0,0 +1,27 @@
|
|||
defmodule AshPhoenix.PlugTest do
|
||||
use ExUnit.Case
|
||||
|
||||
describe "status/1" do
|
||||
test "for individual errors" do
|
||||
error = %Ash.Error.Query.NotFound{}
|
||||
assert 404 == Plug.Exception.status(error)
|
||||
end
|
||||
|
||||
test "for top-level errors wrapping several errors" do
|
||||
error_custom_code = %Ash.Error.Query.NotFound{}
|
||||
|
||||
# This is something that should never happen so will never have a custom status code
|
||||
error_default_code = %Ash.Error.Framework.SynchronousEngineStuck{}
|
||||
|
||||
error = %Ash.Error.Invalid{errors: [error_custom_code]}
|
||||
assert 404 == Plug.Exception.status(error)
|
||||
|
||||
error = %Ash.Error.Invalid{errors: [error_default_code]}
|
||||
assert 500 == Plug.Exception.status(error)
|
||||
|
||||
# The highest error code is used when there are multiple child errors
|
||||
error = %Ash.Error.Invalid{errors: [error_default_code, error_custom_code]}
|
||||
assert 500 == Plug.Exception.status(error)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue