From 1e9e956d00512f611f5d61a26b1dad15878e1032 Mon Sep 17 00:00:00 2001 From: Wondr Date: Sun, 14 Jun 2026 01:44:15 +0100 Subject: [PATCH 1/2] configure json_library to be JSON if defined Fixes #6461 --- lib/phoenix.ex | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/phoenix.ex b/lib/phoenix.ex index 9a4d5b7ac3..3790a82329 100644 --- a/lib/phoenix.ex +++ b/lib/phoenix.ex @@ -45,7 +45,13 @@ defmodule Phoenix do """ def json_library do - Application.get_env(:phoenix, :json_library, Jason) + Application.get_env(:phoenix, :json_library) || default_json_library() + end + + if Code.ensure_loaded?(JSON) do + defp default_json_library, do: JSON + else + defp default_json_library, do: Jason end @doc """ @@ -63,14 +69,22 @@ defmodule Phoenix do end defp warn_on_missing_json_library do - configured_lib = Application.get_env(:phoenix, :json_library) - - if configured_lib && not Code.ensure_loaded?(configured_lib) do - IO.warn(""" - found #{inspect(configured_lib)} in your application configuration - for Phoenix JSON encoding, but module #{inspect(configured_lib)} is not available. - Ensure #{inspect(configured_lib)} is listed as a dependency in mix.exs. - """) + lib = json_library() + + if not Code.ensure_loaded?(lib) do + if configured_lib = Application.get_env(:phoenix, :json_library) do + IO.warn(""" + found #{inspect(configured_lib)} in your application configuration + for Phoenix JSON encoding, but module #{inspect(configured_lib)} is not available. + Ensure #{inspect(configured_lib)} is listed as a dependency in mix.exs. + """) + else + IO.warn(""" + Phoenix requires a JSON library. By default Phoenix uses #{inspect(lib)}, + but module #{inspect(lib)} is not available. + Ensure #{inspect(lib)} is listed as a dependency in mix.exs. + """) + end end end end From cf6c678a60f59d057618275c5204f578b1549be5 Mon Sep 17 00:00:00 2001 From: Wondr Date: Sun, 14 Jun 2026 02:05:05 +0100 Subject: [PATCH 2/2] Support module plug with options in pipe_through --- lib/phoenix/router.ex | 9 ++++++++- test/phoenix/router/pipeline_test.exs | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/phoenix/router.ex b/lib/phoenix/router.ex index e63357bb5b..1b49301d2f 100644 --- a/lib/phoenix/router.ex +++ b/lib/phoenix/router.ex @@ -661,7 +661,14 @@ defmodule Phoenix.Router do end defp build_pipes(name, pipe_through) do - plugs = pipe_through |> Enum.reverse() |> Enum.map(&{&1, [], true}) + plugs = + pipe_through + |> Enum.reverse() + |> Enum.map(fn + {plug, opts} -> {plug, opts, true} + plug -> {plug, [], true} + end) + opts = [init_mode: Phoenix.plug_init_mode(), log_on_halt: :debug] {conn, body} = Plug.Builder.compile(__ENV__, plugs, opts) diff --git a/test/phoenix/router/pipeline_test.exs b/test/phoenix/router/pipeline_test.exs index 3a404f4754..915cf45a5b 100644 --- a/test/phoenix/router/pipeline_test.exs +++ b/test/phoenix/router/pipeline_test.exs @@ -63,6 +63,19 @@ defmodule Phoenix.Router.PipelineTest.Router do get "/", SampleController, :index end + defmodule GreetingPlug do + def init(opts), do: opts + def call(conn, opts) do + greeting = Keyword.get(opts, :greeting, "hello") + conn |> Plug.Conn.assign(:greeting, greeting) + end + end + + scope "/greeting" do + pipe_through [{GreetingPlug, greeting: "Hola!"}] + get "/", SampleController, :index + end + defp stop(conn, _) do conn |> send_resp(200, "stop") |> halt end @@ -114,6 +127,11 @@ defmodule Phoenix.Router.PipelineTest do assert conn.resp_body == "stop" end + test "supports module plug with options" do + conn = call(Router, :get, "/greeting") + assert conn.assigns[:greeting] == "Hola!" + end + test "wraps failures on call" do assert_raise Plug.Conn.WrapperError, fn -> call(Router, :get, "/route_that_crashes")