From f7f69fdbde8270ea46c3cf4da27a1653d7d6087b Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 26 Sep 2024 10:55:13 -0500 Subject: [PATCH 1/2] [GRAPH-1099] Allows a 3-tuple to be return for config errors --- .../phase/subscription/subscribe_self.ex | 20 ++++--- test/absinthe/execution/subscription_test.exs | 53 +++++++++++++++++++ 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/lib/absinthe/phase/subscription/subscribe_self.ex b/lib/absinthe/phase/subscription/subscribe_self.ex index 662ee693..a4f9b07b 100644 --- a/lib/absinthe/phase/subscription/subscribe_self.ex +++ b/lib/absinthe/phase/subscription/subscribe_self.ex @@ -75,25 +75,31 @@ defmodule Absinthe.Phase.Subscription.SubscribeSelf do {:ok, config} {:error, msg} -> - error = %Phase.Error{ - phase: __MODULE__, - message: msg, - locations: [field.source_location] - } + {:error, create_config_error(field, msg)} - {:error, error} + {:error, msg, extra} -> + {:error, create_config_error(field, msg, extra)} val -> raise """ Invalid return from config function! - A config function must return `{:ok, config}` or `{:error, msg}`. You returned: + A config function must return `{:ok, config}`, `{:error, msg}` or `{:error, msg, extra}`. You returned: #{inspect(val)} """ end end + defp create_config_error(field, msg, extra \\ %{}) do + %Phase.Error{ + phase: __MODULE__, + message: msg, + locations: [field.source_location], + extra: extra + } + end + defp get_field_keys(%{schema_node: schema_node} = _field, config) do name = schema_node.identifier diff --git a/test/absinthe/execution/subscription_test.exs b/test/absinthe/execution/subscription_test.exs index 34aa5435..576d7dfd 100644 --- a/test/absinthe/execution/subscription_test.exs +++ b/test/absinthe/execution/subscription_test.exs @@ -214,6 +214,18 @@ defmodule Absinthe.Execution.SubscriptionTest do {:ok, topic: "*", context_id: "*", document_id: op_name} end end + + field :config_error, :string do + config fn _, _ -> + {:error, "failed"} + end + end + + field :config_error_with_extra, :string do + config fn _, _ -> + {:error, "failed", %{code: "FAILED"}} + end + end end mutation do @@ -584,6 +596,47 @@ defmodule Absinthe.Execution.SubscriptionTest do assert_receive(:batch_get_group) end + @query """ + subscription Example { + configError + } + """ + test "config errors" do + assert {:ok, %{errors: [%{message: "failed"}]}} = + run_subscription( + @query, + Schema, + variables: %{}, + context: %{pubsub: PubSub} + ) + end + + @query """ + subscription Example { + configErrorWithExtra + } + """ + test "config errors with extra" do + assert {:ok, %{errors: [%{message: "failed", code: "FAILED"}]}} = + run_subscription( + @query, + Schema, + variables: %{}, + context: %{pubsub: PubSub} + ) + end + + test "config errors with extra and spec_compliant_errors turned on" do + assert {:ok, %{errors: [%{message: "failed", extensions: %{code: "FAILED"}}]}} = + run_subscription( + @query, + Schema, + variables: %{}, + context: %{pubsub: PubSub}, + spec_compliant_errors: true + ) + end + describe "subscription_ids" do @query """ subscription { From ea997533e26891f4c2330c04b06274cf80985c61 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 27 Sep 2024 08:56:17 -0500 Subject: [PATCH 2/2] Accept a map with a message key --- lib/absinthe/phase/document/result.ex | 9 ++++++++ .../phase/subscription/subscribe_self.ex | 20 +++++++----------- test/absinthe/execution/subscription_test.exs | 21 +++++-------------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/lib/absinthe/phase/document/result.ex b/lib/absinthe/phase/document/result.ex index dd6a0928..651555b7 100644 --- a/lib/absinthe/phase/document/result.ex +++ b/lib/absinthe/phase/document/result.ex @@ -109,6 +109,15 @@ defmodule Absinthe.Phase.Document.Result do defp field_name(%{alias: name}), do: name defp field_name(%{name: name}), do: name + defp format_error(%Phase.Error{message: %{message: _message} = error_object} = error, _opts) do + if Enum.empty?(error.locations) do + error_object + else + locations = Enum.flat_map(error.locations, &format_location/1) + Map.put_new(error_object, :locations, locations) + end + end + defp format_error(%Phase.Error{locations: []} = error, opts) do error_object = %{message: error.message} diff --git a/lib/absinthe/phase/subscription/subscribe_self.ex b/lib/absinthe/phase/subscription/subscribe_self.ex index a4f9b07b..662ee693 100644 --- a/lib/absinthe/phase/subscription/subscribe_self.ex +++ b/lib/absinthe/phase/subscription/subscribe_self.ex @@ -75,31 +75,25 @@ defmodule Absinthe.Phase.Subscription.SubscribeSelf do {:ok, config} {:error, msg} -> - {:error, create_config_error(field, msg)} + error = %Phase.Error{ + phase: __MODULE__, + message: msg, + locations: [field.source_location] + } - {:error, msg, extra} -> - {:error, create_config_error(field, msg, extra)} + {:error, error} val -> raise """ Invalid return from config function! - A config function must return `{:ok, config}`, `{:error, msg}` or `{:error, msg, extra}`. You returned: + A config function must return `{:ok, config}` or `{:error, msg}`. You returned: #{inspect(val)} """ end end - defp create_config_error(field, msg, extra \\ %{}) do - %Phase.Error{ - phase: __MODULE__, - message: msg, - locations: [field.source_location], - extra: extra - } - end - defp get_field_keys(%{schema_node: schema_node} = _field, config) do name = schema_node.identifier diff --git a/test/absinthe/execution/subscription_test.exs b/test/absinthe/execution/subscription_test.exs index 576d7dfd..c3355dce 100644 --- a/test/absinthe/execution/subscription_test.exs +++ b/test/absinthe/execution/subscription_test.exs @@ -221,9 +221,9 @@ defmodule Absinthe.Execution.SubscriptionTest do end end - field :config_error_with_extra, :string do + field :config_error_with_map, :string do config fn _, _ -> - {:error, "failed", %{code: "FAILED"}} + {:error, %{message: "failed", extensions: %{code: "FAILED"}}} end end end @@ -613,27 +613,16 @@ defmodule Absinthe.Execution.SubscriptionTest do @query """ subscription Example { - configErrorWithExtra + configErrorWithMap } """ - test "config errors with extra" do - assert {:ok, %{errors: [%{message: "failed", code: "FAILED"}]}} = - run_subscription( - @query, - Schema, - variables: %{}, - context: %{pubsub: PubSub} - ) - end - - test "config errors with extra and spec_compliant_errors turned on" do + test "config errors with a map" do assert {:ok, %{errors: [%{message: "failed", extensions: %{code: "FAILED"}}]}} = run_subscription( @query, Schema, variables: %{}, - context: %{pubsub: PubSub}, - spec_compliant_errors: true + context: %{pubsub: PubSub} ) end