Repository: phoenixframework/phoenix
Pull request #3609 (2019-11-11 23:02:53)

Bump phoenix_html.js to v2.13.3
When generating an app with the `--no-webpack` option, delete links don't work with _v2.10.0_ of the mentioned file.


Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6a0128722..f58ab774f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -207,7 +207,7 @@ of beginning users because expert users have more tools at their disposal to
 help themselves.
 
 The general pattern we use for presenting information is to first introduce a
-small, discreet topic, then write a small amount of code to demonstrate the
+small, discrete topic, then write a small amount of code to demonstrate the
 concept, then verify that the code worked.
 
 In this way, we build from small, easily digestible concepts into more complex
diff --git a/guides/ecto.md b/guides/ecto.md
index bde6f1715..3846e1242 100644
--- a/guides/ecto.md
+++ b/guides/ecto.md
@@ -11,7 +11,7 @@ Newly generated Phoenix projects include Ecto with the PostgreSQL adapter by def
 
 For a thorough, general guide for Ecto, check out the [Ecto getting started guide](https://hexdocs.pm/ecto/getting-started.html). For an overview of all Ecto specific mix tasks for Phoenix, see the [mix tasks guide](phoenix_mix_tasks.html#ecto-specific-mix-tasks).
 
-This guide assumes that we have generated our new application with Ecto integration and that we will be using PostgreSQL. For instructions on switching to MySQL, please see the [Using MySQL](ecto.html#using-mysql) section.
+This guide assumes that we have generated our new application with Ecto integration and that we will be using PostgreSQL. For instructions on switching to MySQL, please see the [Using MySQL](#using-mysql) section.
 
 The default Postgres configuration has a superuser account with username 'postgres' and the password 'postgres'. If you take a look at the file `config/dev.exs`, you'll see that Phoenix works off this assumption. If you don't have this account already setup on your machine, you can connect to your postgres instance by typing `psql` and then entering the following commands:
 
diff --git a/guides/errors.md b/guides/errors.md
index fb5536ec3..a4de46e96 100644
--- a/guides/errors.md
+++ b/guides/errors.md
@@ -72,7 +72,7 @@ defmodule Phoenix.Router do
 end
 ```
 
-Plug provides a protocol called `Plug.Exception` specifically for adding a status to exception structs.
+Plug provides a protocol called `Plug.Exception` where we are able to customize the status and add actions that exception structs can returns on the debug error page.
 
 If we wanted to supply a status of 404 for an `Ecto.NoResultsError`, we could do it by defining an implementation for the `Plug.Exception` protocol like this:
 
@@ -83,3 +83,20 @@ end
 ```
 
 Note that this is just an example: Phoenix [already does this](https://github.com/phoenixframework/phoenix_ecto/blob/master/lib/phoenix_ecto/plug.ex) for `Ecto.NoResultsError`, so you don't have to.
+
+#### Actions
+
+Actions are functions that can be triggered by the error page, it is basically a list of maps defining a `label` and a `handler` to be executed.
+It is rendered in the error page as a collection of buttons and follows the format of: `[%{label: String.t(), handler: {module(), function :: atom(), args :: []}}]`.
+
+If we wanted to return some actions for an `Ecto.NoResultsError` we would implement `Plug.Exception` like this:
+
+```elixir
+defimpl Plug.Exception, for: Ecto.NoResultsError do
+  def status(_exception), do: 404
+  def actions(_exception), do: [%{
+      label: "Run seeds",
+      handler: {Code, :eval_file, "priv/repo/seeds.exs"}
+    }]
+end
+```
\ No newline at end of file
diff --git a/installer/templates/phx_single/mix.exs b/installer/templates/phx_single/mix.exs
index 6f539d93f..567f90a4a 100644
--- a/installer/templates/phx_single/mix.exs
+++ b/installer/templates/phx_single/mix.exs
@@ -38,7 +38,7 @@ defmodule <%= app_module %>.MixProject do
   defp deps do
     [
       <%= phoenix_dep %>,<%= if ecto do %>
-      {:phoenix_ecto, "~> 4.0"},
+      {:phoenix_ecto, "~> 4.1"},
       {:ecto_sql, "~> 3.1"},
       {<%= inspect adapter_app %>, ">= 0.0.0"},<% end %><%= if html do %>
       {:phoenix_html, "~> 2.11"},
diff --git a/installer/templates/phx_static/app.js b/installer/templates/phx_static/app.js
index 05738f458..69bf58f0b 100644
--- a/installer/templates/phx_static/app.js
+++ b/installer/templates/phx_static/app.js
@@ -1,3 +1,3 @@
 // for phoenix_html support, including form and button helpers
 // copy the following scripts into your javascript bundle:
-// * https://raw.githubusercontent.com/phoenixframework/phoenix_html/v2.10.0/priv/static/phoenix_html.js
+// * https://raw.githubusercontent.com/phoenixframework/phoenix_html/master/priv/static/phoenix_html.js
diff --git a/installer/templates/phx_web/endpoint.ex b/installer/templates/phx_web/endpoint.ex
index 4ebc796ec..8efd62e8c 100644
--- a/installer/templates/phx_web/endpoint.ex
+++ b/installer/templates/phx_web/endpoint.ex
@@ -20,7 +20,8 @@ defmodule <%= endpoint_module %> do
   if code_reloading? do<%= if html do %>
     socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
     plug Phoenix.LiveReloader<% end %>
-    plug Phoenix.CodeReloader
+    plug Phoenix.CodeReloader<%= if ecto do %>
+    plug Phoenix.Ecto.CheckRepoStatus, otp_app: :<%= web_app_name %><% end %>
   end
 
   plug Plug.RequestId
diff --git a/lib/phoenix/exceptions.ex b/lib/phoenix/exceptions.ex
index a3c6b13e6..c4ad363b2 100644
--- a/lib/phoenix/exceptions.ex
+++ b/lib/phoenix/exceptions.ex
@@ -56,7 +56,7 @@ defmodule Phoenix.ActionClauseError do
     {exception, stacktrace} =
       exception
       |> Map.put(:__struct__, FunctionClauseError)
-      |> FunctionClauseError.blame(exception, stacktrace)
+      |> FunctionClauseError.blame(stacktrace)
 
     exception = Map.put(exception, :__struct__, __MODULE__)
 
diff --git a/lib/phoenix/template.ex b/lib/phoenix/template.ex
index 1ea100402..ef3c38c8f 100644
--- a/lib/phoenix/template.ex
+++ b/lib/phoenix/template.ex
@@ -116,7 +116,7 @@ defmodule Phoenix.Template do
     def message(exception) do
       "Could not render #{inspect exception.template} for #{inspect exception.module}, "
         <> "please define a matching clause for render/2 or define a template at "
-        <> "#{inspect Path.relative_to_cwd exception.root}. "
+        <> "#{inspect Path.join(Path.relative_to_cwd(exception.root), exception.pattern)}. "
         <> available_templates(exception.available)
         <> "\nAssigns:\n\n"
         <> inspect(exception.assigns)


Test patch:
diff --git a/installer/test/phx_new_test.exs b/installer/test/phx_new_test.exs
index fc126583a..feab93a83 100644
--- a/installer/test/phx_new_test.exs
+++ b/installer/test/phx_new_test.exs
@@ -133,6 +133,7 @@ defmodule Mix.Tasks.Phx.NewTest do
       assert_file "phx_blog/test/support/data_case.ex", ~r"defmodule PhxBlog.DataCase"
       assert_file "phx_blog/lib/phx_blog_web.ex", ~r"defmodule PhxBlogWeb"
       assert_file "phx_blog/priv/repo/migrations/.formatter.exs", ~r"import_deps: \[:ecto_sql\]"
+      assert_file "phx_blog/lib/phx_blog_web/endpoint.ex", ~r"plug Phoenix.Ecto.CheckRepoStatus, otp_app: :phx_blog"
 
       # Install dependencies?
       assert_received {:mix_shell, :yes?, ["\nFetch and install dependencies?"]}
@@ -178,6 +179,9 @@ defmodule Mix.Tasks.Phx.NewTest do
       # No Ecto
       config = ~r/config :phx_blog, PhxBlog.Repo,/
       refute File.exists?("phx_blog/lib/phx_blog/repo.ex")
+      assert_file "phx_blog/lib/phx_blog_web/endpoint.ex", fn file ->
+        refute file =~ "plug Phoenix.Ecto.CheckRepoStatus, otp_app: :phx_blog"
+      end
 
       # No gettext
       refute_file "phx_blog/lib/phx_blog_web/gettext.ex"
diff --git a/lib/phoenix/test/conn_test.ex b/lib/phoenix/test/conn_test.ex
index 54e4b0e1c..783921378 100644
--- a/lib/phoenix/test/conn_test.ex
+++ b/lib/phoenix/test/conn_test.ex
@@ -369,7 +369,7 @@ defmodule Phoenix.ConnTest do
   end
 
   @doc """
-  Asserts the given status code, that we have an text response and
+  Asserts the given status code, that we have a text response and
   returns the response body if one was set or sent.
 
   ## Examples
@@ -384,7 +384,7 @@ defmodule Phoenix.ConnTest do
   end
 
   @doc """
-  Asserts the given status code, that we have an json response and
+  Asserts the given status code, that we have a json response and
   returns the decoded JSON response if one was set or sent.
 
   ## Examples
@@ -542,7 +542,7 @@ defmodule Phoenix.ConnTest do
   end
 
   @doc """
-  Calls the Endpoint and and the given Router pipelines.
+  Calls the Endpoint and the given Router pipelines.
 
   See `bypass_through/1`.
   """