All checks were successful
deploy / deploy (push) Successful in 3m36s
Image variants were written to the ephemeral release directory and wiped on every deploy, causing 500 errors with 50s timeouts as browsers waited for images that could never be served. - Point image_cache_dir at /data/image_cache in prod - Add Plug.Static to serve from the persistent volume - Exclude /image_cache/ from broken URL tracking Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
41 lines
1.2 KiB
Elixir
41 lines
1.2 KiB
Elixir
defmodule BerrypodWeb.Plugs.BrokenUrlTracker do
|
|
@moduledoc """
|
|
Wraps the router to record 404s in the broken URLs table.
|
|
|
|
Works in dev mode too — Plug.Debugger intercepts exceptions before
|
|
error templates render, so we catch NoRouteError here, record it,
|
|
then re-raise so the normal error handling continues.
|
|
"""
|
|
|
|
@behaviour Plug
|
|
|
|
def init(opts) do
|
|
router = Keyword.fetch!(opts, :router)
|
|
router_opts = router.init([])
|
|
{router, router_opts}
|
|
end
|
|
|
|
def call(conn, {router, router_opts}) do
|
|
router.call(conn, router_opts)
|
|
rescue
|
|
e in Phoenix.Router.NoRouteError ->
|
|
unless static_path?(conn.request_path) do
|
|
prior_hits = Berrypod.Analytics.count_pageviews_for_path(conn.request_path)
|
|
Berrypod.Redirects.record_broken_url(conn.request_path, prior_hits)
|
|
|
|
if prior_hits > 0 do
|
|
Berrypod.Redirects.attempt_auto_resolve(conn.request_path)
|
|
end
|
|
end
|
|
|
|
reraise e, __STACKTRACE__
|
|
end
|
|
|
|
defp static_path?(path) do
|
|
String.starts_with?(path, "/assets/") or
|
|
String.starts_with?(path, "/images/") or
|
|
String.starts_with?(path, "/image_cache/") or
|
|
String.starts_with?(path, "/favicon")
|
|
end
|
|
end
|