From 2ade23629ca84512a3c4c3eb1680015f9efe77bf Mon Sep 17 00:00:00 2001 From: Vince DeVendra Date: Mon, 30 Jan 2023 14:28:22 -0500 Subject: [PATCH 1/4] Rescue exceptions, raise Plug.Conn.WrapperError --- lib/absinthe/plug.ex | 68 ++++++++++--------- .../absinthe/plug/document_provider_test.exs | 2 +- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/lib/absinthe/plug.ex b/lib/absinthe/plug.ex index e780216..dd04dec 100644 --- a/lib/absinthe/plug.ex +++ b/lib/absinthe/plug.ex @@ -286,37 +286,43 @@ defmodule Absinthe.Plug do """ @spec call(Plug.Conn.t(), map) :: Plug.Conn.t() | no_return def call(conn, config) do - config = update_config(conn, config) - {conn, result} = conn |> execute(config) - - case result do - {:input_error, msg} -> - conn - |> encode(400, error_result(msg), config) - - {:ok, %{"subscribed" => topic}} -> - conn - |> subscribe(topic, config) - - {:ok, %{data: _} = result} -> - conn - |> encode(200, result, config) - - {:ok, %{errors: _} = result} -> - conn - |> encode(200, result, config) - - {:ok, result} when is_list(result) -> - conn - |> encode(200, result, config) - - {:error, {:http_method, text}, _} -> - conn - |> encode(405, error_result(text), config) - - {:error, error, _} when is_binary(error) -> - conn - |> encode(500, error_result(error), config) + try do + config = update_config(conn, config) + {conn, result} = conn |> execute(config) + + case result do + {:input_error, msg} -> + conn + |> encode(400, error_result(msg), config) + + {:ok, %{"subscribed" => topic}} -> + conn + |> subscribe(topic, config) + + {:ok, %{data: _} = result} -> + conn + |> encode(200, result, config) + + {:ok, %{errors: _} = result} -> + conn + |> encode(200, result, config) + + {:ok, result} when is_list(result) -> + conn + |> encode(200, result, config) + + {:error, {:http_method, text}, _} -> + conn + |> encode(405, error_result(text), config) + + {:error, error, _} when is_binary(error) -> + conn + |> encode(500, error_result(error), config) + end + catch + kind, reason -> + stack = __STACKTRACE__ + Plug.Conn.WrapperError.reraise(conn, kind, reason, stack) end end diff --git a/test/lib/absinthe/plug/document_provider_test.exs b/test/lib/absinthe/plug/document_provider_test.exs index ecdcec5..2690368 100644 --- a/test/lib/absinthe/plug/document_provider_test.exs +++ b/test/lib/absinthe/plug/document_provider_test.exs @@ -50,7 +50,7 @@ defmodule Absinthe.Plug.DocumentProviderTest do test "cannot process without any document providers" do opts = Absinthe.Plug.init(schema: TestSchema, document_providers: []) - assert_raise RuntimeError, fn -> request(opts) end + assert_raise Plug.Conn.WrapperError, fn -> request(opts) end end defp request(opts) do From c8a798084055de9c29ae317d4038833b88f8eada Mon Sep 17 00:00:00 2001 From: Vince DeVendra Date: Mon, 30 Jan 2023 15:53:34 -0500 Subject: [PATCH 2/4] Use compatible ubuntu for workflow --- .github/workflows/elixir.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 6a4984c..c7efe5d 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -9,7 +9,7 @@ on: jobs: test: name: Elixir ${{matrix.elixir}} / OTP ${{matrix.otp}} - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: matrix: From 743f96cd7846d453a9d20b5532d0def49cba753b Mon Sep 17 00:00:00 2001 From: Vince DeVendra Date: Tue, 31 Jan 2023 09:43:26 -0500 Subject: [PATCH 3/4] Add a test case --- test/lib/absinthe/plug_test.exs | 14 ++++++++++++++ test/support/test_schema.ex | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/test/lib/absinthe/plug_test.exs b/test/lib/absinthe/plug_test.exs index 975ebc6..7c48281 100644 --- a/test/lib/absinthe/plug_test.exs +++ b/test/lib/absinthe/plug_test.exs @@ -707,6 +707,20 @@ defmodule Absinthe.PlugTest do end end + test "raises wrapped error with plugged conn on uncaught exceptions" do + opts = Absinthe.Plug.init(schema: TestSchema) + body = %{query: "{ exceptionRaising }"} + + exception = assert_raise Plug.Conn.WrapperError, fn -> + conn(:post, "/", body) + |> put_req_header("content-type", "application/json") + |> plug_parser + |> Absinthe.Plug.call(opts) + end + + assert exception.conn.body_params == %{"query" => "{ exceptionRaising }"} + end + def test_before_send(conn, val) do # just for easy testing send(self(), {:before_send, val}) diff --git a/test/support/test_schema.ex b/test/support/test_schema.ex index 47582cd..4fec7b7 100644 --- a/test/support/test_schema.ex +++ b/test/support/test_schema.ex @@ -66,6 +66,12 @@ defmodule Absinthe.Plug.TestSchema do raise "complex string must not be resolved" end end + + field :exception_raising, :string do + resolve fn _, _ -> + raise "uncaught exception" + end + end end subscription do From 61eeb8d9434892443488352c0e58667b4902efaa Mon Sep 17 00:00:00 2001 From: Vince DeVendra Date: Wed, 1 Feb 2023 12:18:44 -0500 Subject: [PATCH 4/4] Run mix format --- test/lib/absinthe/plug_test.exs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/lib/absinthe/plug_test.exs b/test/lib/absinthe/plug_test.exs index 7c48281..da8a05c 100644 --- a/test/lib/absinthe/plug_test.exs +++ b/test/lib/absinthe/plug_test.exs @@ -711,12 +711,13 @@ defmodule Absinthe.PlugTest do opts = Absinthe.Plug.init(schema: TestSchema) body = %{query: "{ exceptionRaising }"} - exception = assert_raise Plug.Conn.WrapperError, fn -> - conn(:post, "/", body) - |> put_req_header("content-type", "application/json") - |> plug_parser - |> Absinthe.Plug.call(opts) - end + exception = + assert_raise Plug.Conn.WrapperError, fn -> + conn(:post, "/", body) + |> put_req_header("content-type", "application/json") + |> plug_parser + |> Absinthe.Plug.call(opts) + end assert exception.conn.body_params == %{"query" => "{ exceptionRaising }"} end