fix: add error message to form
This commit is contained in:
parent
c31392e4fe
commit
584442076e
2 changed files with 222 additions and 1 deletions
|
|
@ -295,11 +295,14 @@ defmodule MvWeb.MemberLive.Form do
|
|||
handle_save_success(socket, member)
|
||||
|
||||
{:error, form} ->
|
||||
{:noreply, assign(socket, form: form)}
|
||||
handle_save_error(socket, form)
|
||||
end
|
||||
rescue
|
||||
_e in [Ash.Error.Forbidden, Ash.Error.Forbidden.Policy] ->
|
||||
handle_save_forbidden(socket)
|
||||
|
||||
e ->
|
||||
handle_save_exception(socket, e)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -321,6 +324,13 @@ defmodule MvWeb.MemberLive.Form do
|
|||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp handle_save_error(socket, form) do
|
||||
# Always show a flash message when save fails
|
||||
# Field-level validation errors are displayed in form fields, but flash provides additional feedback
|
||||
error_message = extract_error_message(form)
|
||||
{:noreply, socket |> assign(form: form) |> put_flash(:error, error_message)}
|
||||
end
|
||||
|
||||
defp handle_save_forbidden(socket) do
|
||||
# Handle policy violations that aren't properly displayed in forms
|
||||
# AshPhoenix.Form doesn't implement FormData.Error protocol for Forbidden errors
|
||||
|
|
@ -332,6 +342,77 @@ defmodule MvWeb.MemberLive.Form do
|
|||
{:noreply, put_flash(socket, :error, error_message)}
|
||||
end
|
||||
|
||||
defp handle_save_exception(socket, exception) do
|
||||
# Handle unexpected exceptions (database errors, network issues, etc.)
|
||||
require Logger
|
||||
Logger.error("Unexpected error saving member: #{inspect(exception)}")
|
||||
|
||||
action = get_action_name(socket.assigns.form.source.type)
|
||||
error_message = gettext("Failed to %{action} member.", action: action)
|
||||
|
||||
{:noreply, put_flash(socket, :error, error_message)}
|
||||
end
|
||||
|
||||
# Extracts a user-friendly error message from form errors
|
||||
defp extract_error_message(form) do
|
||||
# Try to extract message from source errors first
|
||||
source_errors = get_source_errors(form)
|
||||
|
||||
case source_errors do
|
||||
[%Ash.Error.Invalid{errors: errors} | _] when is_list(errors) ->
|
||||
# Extract first error message
|
||||
case List.first(errors) do
|
||||
%{message: message} when is_binary(message) ->
|
||||
gettext("Validation failed: %{message}", message: message)
|
||||
|
||||
%{field: field, message: message} when is_binary(message) ->
|
||||
gettext("Validation failed: %{field} %{message}", field: field, message: message)
|
||||
|
||||
_ ->
|
||||
gettext("Validation failed. Please check your input.")
|
||||
end
|
||||
|
||||
[error | _] ->
|
||||
# Try to extract message from other error types
|
||||
case error do
|
||||
%{message: message} when is_binary(message) -> message
|
||||
error when is_struct(error) ->
|
||||
# Try to use Ash.ErrorKind protocol if available
|
||||
try do
|
||||
Ash.ErrorKind.message(error)
|
||||
rescue
|
||||
Protocol.UndefinedError -> gettext("Failed to save member. Please try again.")
|
||||
end
|
||||
_ -> gettext("Failed to save member. Please try again.")
|
||||
end
|
||||
|
||||
_ ->
|
||||
# Check if there are any field errors in the form
|
||||
if has_form_errors?(form) do
|
||||
gettext("Please correct the errors in the form and try again.")
|
||||
else
|
||||
gettext("Failed to save member. Please try again.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Checks if form has any errors
|
||||
defp has_form_errors?(form) do
|
||||
case Map.get(form, :errors) do
|
||||
errors when is_list(errors) and length(errors) > 0 -> true
|
||||
_ -> false
|
||||
end
|
||||
end
|
||||
|
||||
# Extracts source-level errors from form (Ash errors, etc.)
|
||||
defp get_source_errors(form) do
|
||||
case form.source do
|
||||
%{errors: errors} when is_list(errors) -> errors
|
||||
%Ash.Changeset{errors: errors} when is_list(errors) -> errors
|
||||
_ -> []
|
||||
end
|
||||
end
|
||||
|
||||
defp get_action_name(:create), do: gettext("create")
|
||||
defp get_action_name(:update), do: gettext("update")
|
||||
defp get_action_name(other), do: to_string(other)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue