feat: add custom HTTP status codes for specific types of errors that can be thrown (#62)

This commit is contained in:
Rebecca Le 2022-11-23 16:42:06 +08:00 committed by GitHub
parent 3ec3a3941c
commit ac3e2dc9ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 0 deletions

View 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
View 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