Skip to content

Instantly share code, notes, and snippets.

@maartenvanvliet
Created September 19, 2022 18:58
Show Gist options
  • Save maartenvanvliet/101da0e8364f9e622563c8456fae2fef to your computer and use it in GitHub Desktop.
Save maartenvanvliet/101da0e8364f9e622563c8456fae2fef to your computer and use it in GitHub Desktop.
Interface errors Stage 6a: Error Union List + Interface
# https://productionreadygraphql.com/2020-08-01-guide-to-graphql-errors
defmodule Absinthe.ErrorInterfaceTest do
use Absinthe.Case, async: true
defmodule TestSchema do
use Absinthe.Schema
query do
field :foo, :string
end
import_sdl """
type User {
id: ID!
name: String!
}
type CreateUserPayload {
user: User
userErrors: [CreateUserError!]!
}
type Mutation {
createUser(error: String!): CreateUserPayload
}
union CreateUserError = UserNameTaken | PasswordTooShort
type UserNameTaken implements UserError {
message: String!
path: String!
suggestion: String!
}
type PasswordTooShort implements UserError {
message: String!
path: String!
length: Int!
}
interface UserError {
message: String!
path: String!
}
"""
def hydrate(%Absinthe.Blueprint{}, _) do
%{
mutation: %{
create_user: {:resolve, &__MODULE__.create_user/2}
},
user_error: {:resolve_type, &__MODULE__.resolve_type/1},
create_user_error: {:resolve_type, &__MODULE__.resolve_error_type/2}
}
end
def hydrate(_node, _ancestors), do: []
def resolve_type(_), do: false
def resolve_error_type(%{suggestion: _}, _), do: :user_name_taken
def resolve_error_type(_, _), do: :password_too_short
def create_user(%{error: "PasswordTooShort"}, _),
do: {:ok, %{user: nil, user_errors: [%{message: "bar", path: "baz", length: 3}]}}
def create_user(%{error: "UserNameTaken"}, _),
do: {:ok, %{user: nil, user_errors: [%{message: "foo", path: "quz", suggestion: "baa"}]}}
end
@query """
mutation($error: String!) {
createUser(error: $error) {
user { id }
userErrors {
# Specific cases
... on UserNameTaken {
message
path
suggestion
}
# Interface contract
... on UserError {
message
path
}
}
}
}
"""
test "mutation on specific case" do
assert {:ok,
%{
data: %{
"createUser" => %{
"user" => nil,
"userErrors" => [%{"message" => "foo", "path" => "quz", "suggestion" => "baa"}]
}
}
}} = Absinthe.run(@query, TestSchema, variables: %{"error" => "UserNameTaken"})
end
test "mutation on interface case" do
assert {:ok,
%{
data: %{
"createUser" => %{
"user" => nil,
"userErrors" => [%{"message" => "bar", "path" => "baz"}]
}
}
}} = Absinthe.run(@query, TestSchema, variables: %{"error" => "PasswordTooShort"})
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment