Packages
absinthe
1.4.10
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/parse.ex
defmodule Absinthe.Phase.Parse do
@moduledoc false
use Absinthe.Phase
alias Absinthe.{Language, Phase}
@spec run(Language.Source.t(), Keyword.t()) :: Phase.result_t()
def run(input, options \\ [])
def run(%Absinthe.Blueprint{} = blueprint, options) do
options = Map.new(options)
case parse(blueprint.input) do
{:ok, value} ->
{:ok, %{blueprint | input: value}}
{:error, error} ->
blueprint
|> add_validation_error(error)
|> handle_error(options)
end
end
def run(input, options) do
run(%Absinthe.Blueprint{input: input}, options)
end
defp add_validation_error(bp, error) do
put_in(bp.execution.validation_errors, [error])
end
def handle_error(blueprint, %{jump_phases: true, result_phase: abort_phase}) do
{:jump, blueprint, abort_phase}
end
def handle_error(blueprint, _) do
{:error, blueprint}
end
@spec tokenize(binary) :: {:ok, [tuple]} | {:error, binary}
defp tokenize(input) do
chars = :erlang.binary_to_list(input)
case :absinthe_lexer.string(chars) do
{:ok, tokens, _line_count} ->
{:ok, tokens}
{:error, raw_error, _} ->
{:error, format_raw_parse_error(raw_error)}
end
end
@spec parse(binary) :: {:ok, Language.Document.t()} | {:error, tuple}
@spec parse(Language.Source.t()) :: {:ok, Language.Document.t()} | {:error, tuple}
defp parse(input) when is_binary(input) do
parse(%Language.Source{body: input})
end
defp parse(input) do
try do
case input.body |> tokenize do
{:ok, []} ->
{:ok, %Language.Document{}}
{:ok, tokens} ->
case :absinthe_parser.parse(tokens) do
{:ok, _doc} = result ->
result
{:error, raw_error} ->
{:error, format_raw_parse_error(raw_error)}
end
other ->
other
end
rescue
error ->
{:error, format_raw_parse_error(error)}
end
end
@spec format_raw_parse_error({integer, :absinthe_parser, [charlist]}) :: Phase.Error.t()
defp format_raw_parse_error({line, :absinthe_parser, msgs}) do
message = msgs |> Enum.map(&to_string/1) |> Enum.join("")
%Phase.Error{message: message, locations: [%{line: line, column: 0}], phase: __MODULE__}
end
@spec format_raw_parse_error({integer, :absinthe_lexer, {atom, charlist}}) :: Phase.Error.t()
defp format_raw_parse_error({line, :absinthe_lexer, {problem, field}}) do
message = "#{problem}: #{field}"
%Phase.Error{message: message, locations: [%{line: line, column: 0}], phase: __MODULE__}
end
@unknown_error_msg "An unknown error occurred during parsing"
@spec format_raw_parse_error(map) :: Phase.Error.t()
defp format_raw_parse_error(%{} = error) do
detail =
if Exception.exception?(error) do
": " <> Exception.message(error)
else
""
end
%Phase.Error{message: @unknown_error_msg <> detail, phase: __MODULE__}
end
end