Packages
absinthe
1.7.1
1.11.0
1.10.2
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.8
1.6.7
retired
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-rc.1
1.6.0-rc.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.5.0-rc.5
1.5.0-rc.4
1.5.0-rc.3
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.5.0-beta.2
1.5.0-beta.1
1.5.0-beta.0
1.5.0-alpha.4
1.5.0-alpha.3
1.5.0-alpha.2
1.5.0-alpha.1
1.5.0-alpha.0
1.4.16
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
retired
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.3
1.4.0-rc.2
1.4.0-rc.1
1.4.0-rc.0
1.4.0-beta.5
1.4.0-beta.4
1.4.0-beta.3
1.4.0-beta.2
1.4.0-beta.1
1.3.2
1.3.1
1.3.0
1.3.0-rc.0
1.3.0-beta.2
1.3.0-beta.1
1.3.0-beta.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.2.0-beta.0
1.2.0-alpha0
1.2.0-alpha.2
1.2.0-alpha.1
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.2.3
0.2.2
0.2.1
0.1.0
GraphQL for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/absinthe/phase/document/complexity/result.ex
defmodule Absinthe.Phase.Document.Complexity.Result do
@moduledoc false
# Collects complexity errors into the result.
alias Absinthe.{Blueprint, Phase}
use Absinthe.Phase
@doc """
Run the validation.
"""
@spec run(Blueprint.t(), Keyword.t()) :: Phase.result_t()
def run(input, options \\ []) do
max = Keyword.get(options, :max_complexity, :infinity)
operation = Blueprint.current_operation(input)
fun = &handle_node(&1, max, &2)
{operation, errors} = Blueprint.prewalk(operation, [], fun)
blueprint = Blueprint.update_current(input, fn _ -> operation end)
blueprint = put_in(blueprint.execution.validation_errors, errors)
case {errors, Map.new(options)} do
{[], _} ->
{:ok, blueprint}
{_errors, %{jump_phases: true, result_phase: abort_phase}} ->
{:jump, blueprint, abort_phase}
_ ->
{:error, blueprint}
end
end
defp handle_node(%{complexity: complexity} = node, max, errors)
when is_integer(complexity) and complexity > max do
error = error(node, complexity, max)
node =
node
|> flag_invalid(:too_complex)
|> put_error(error)
{node, [error | errors]}
end
defp handle_node(%{complexity: _} = node, _, errors) do
{:halt, node, errors}
end
defp handle_node(node, _, errors) do
{node, errors}
end
defp error(%{source_location: location} = node, complexity, max) do
%Phase.Error{
phase: __MODULE__,
message: error_message(node, complexity, max),
locations: [location]
}
end
def error_message(node, complexity, max) do
"#{describe_node(node)} is too complex: complexity is #{complexity} and maximum is #{max}"
end
defp describe_node(%Blueprint.Document.Operation{name: nil}) do
"Operation"
end
defp describe_node(%Blueprint.Document.Operation{name: name}) do
"Operation #{name}"
end
defp describe_node(%Blueprint.Document.Field{name: name}) do
"Field #{name}"
end
defp describe_node(%Blueprint.Document.Fragment.Spread{name: name}) do
"Spread #{name}"
end
defp describe_node(%Blueprint.Document.Fragment.Inline{}) do
"Inline Fragment"
end
end