Last active
September 13, 2021 16:46
-
-
Save trbngr/024e30cba704885a68105b91fbda514e to your computer and use it in GitHub Desktop.
Absinthe Handle Exceptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Middleware.HandleExceptions do | |
require Logger | |
alias Absinthe.Resolution | |
alias Ecto.Query.CastError | |
alias AbsintheErrorPayload.ChangesetParser | |
alias Ecto.{InvalidChangesetError, NoResultsError, StaleEntryError} | |
def handle_exceptions(middleware_spec) do | |
fn resolution, config -> | |
middleware_spec | |
|> wrap_middleware(resolution, config) | |
|> execute(resolution) | |
end | |
end | |
defp wrap_middleware({{mod, fun}, config}, resolution, _config) do | |
fn -> apply(mod, fun, [resolution, config]) end | |
end | |
defp wrap_middleware({mod, config}, resolution, _config) do | |
fn -> apply(mod, :call, [resolution, config]) end | |
end | |
defp wrap_middleware(mod, resolution, config) when is_atom(mod) do | |
fn -> apply(mod, :call, [resolution, config]) end | |
end | |
defp wrap_middleware(fun, resolution, config) when is_function(fun, 2) do | |
fn -> fun.(resolution, config) end | |
end | |
defp execute(fun, res) do | |
fun.() | |
rescue | |
e in CastError -> | |
type = if e.type === :binary_id, do: :uuid, else: e.type | |
error = [message: "Invalid argument", type: type, value: e.value, status: 400] | |
Resolution.put_result(res, {:error, error}) | |
_ in NoResultsError -> | |
error = [message: "Not found", status: 404] | |
Resolution.put_result(res, {:error, error}) | |
e in StaleEntryError -> | |
Resolution.put_result( | |
res, | |
{:error, [message: "Not found.", status: 404, detail: Exception.message(e)]} | |
) | |
e in InvalidChangesetError -> | |
errors = | |
e.changeset | |
|> ChangesetParser.extract_messages() | |
|> Enum.map(&"#{&1.field} #{&1.message}") | |
Resolution.put_result(res, {:error, errors}) | |
e -> | |
Logger.error("Unexpected error", error: e, stacktrace: __STACKTRACE__) | |
Resolution.put_result(res, {:error, Exception.message(e)}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule MySchema do | |
... | |
def middleware(middleware, _field, _object) do | |
Enum.map(middleware, &Middleware.HandleExceptions.handle_exceptions/1) | |
end | |
... | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment