Packages
absinthe
1.6.4
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.{Blueprint, Language, Phase}
# This is because Dialyzer is telling us tokenizing can never fail,
# but we know it's possible.
@dialyzer {:no_match, run: 2}
@spec run(Language.Source.t() | %Blueprint{}, 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
# This is because Dialyzer is telling us tokenizing can never fail,
# but we know it's possible.
@dialyzer {:no_unused, add_validation_error: 2}
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, String.t()}
def tokenize(input) do
case Absinthe.Lexer.tokenize(input) do
{:error, rest, loc} ->
{:error, format_raw_parse_error({:lexer, rest, loc})}
other ->
other
end
end
# This is because Dialyzer is telling us tokenizing can never fail,
# but we know it's possible.
@dialyzer {:no_match, parse: 1}
@spec parse(binary | 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 tokenize(input.body) 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, integer}, :absinthe_parser, [charlist]}) ::
Phase.Error.t()
defp format_raw_parse_error({{line, column}, :absinthe_parser, msgs}) do
message = msgs |> Enum.map(&to_string/1) |> Enum.join("")
%Phase.Error{message: message, locations: [%{line: line, column: column}], phase: __MODULE__}
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({:lexer, String.t(), {line :: pos_integer, column :: pos_integer}}) ::
Phase.Error.t()
defp format_raw_parse_error({:lexer, rest, {line, column}}) do
sample = String.slice(rest, 0, 10)
message = "Parsing failed at `#{sample}`"
%Phase.Error{message: message, locations: [%{line: line, column: column}], 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