From ec6422d450ccb2f62d447861a4ed790e99c6d05e Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 2 Jun 2026 12:08:19 +0200 Subject: [PATCH] fix(membership-fees): show error for unparseable cycle date instead of crashing Date.from_iso8601/1 returns {:error, reason}, so the with else clause matching a bare :error never fired and an invalid date raised a WithClauseError. Match the real date/calendar error reasons so the user sees the validation message. --- .../show/membership_fees_component.ex | 2 +- .../member_live/show_membership_fees_test.exs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/mv_web/live/member_live/show/membership_fees_component.ex b/lib/mv_web/live/member_live/show/membership_fees_component.ex index e8ddff4..0cba316 100644 --- a/lib/mv_web/live/member_live/show/membership_fees_component.ex +++ b/lib/mv_web/live/member_live/show/membership_fees_component.ex @@ -1027,7 +1027,7 @@ defmodule MvWeb.MemberLive.Show.MembershipFeesComponent do |> assign(:create_cycle_error, format_error(error))} end else - :error -> + {:error, reason} when reason in [:invalid_format, :invalid_date, :incompatible_calendars] -> {:noreply, socket |> assign(:create_cycle_error, gettext("Invalid date format"))} diff --git a/test/mv_web/member_live/show_membership_fees_test.exs b/test/mv_web/member_live/show_membership_fees_test.exs index 2abb0cb..59dc471 100644 --- a/test/mv_web/member_live/show_membership_fees_test.exs +++ b/test/mv_web/member_live/show_membership_fees_test.exs @@ -268,6 +268,28 @@ defmodule MvWeb.MemberLive.ShowMembershipFeesTest do # Should not crash assert html =~ member.first_name end + + test "create_cycle with an unparseable date shows an error instead of crashing", %{conn: conn} do + fee_type = create_fee_type(%{interval: :yearly}) + member = Mv.Fixtures.member_fixture(%{membership_fee_type_id: fee_type.id}) + + {:ok, view, _html} = live(conn, "/members/#{member.id}") + + view + |> element("button[phx-click='switch_tab'][phx-value-tab='membership_fees']") + |> render_click() + + view + |> element("button[phx-click='open_create_cycle_modal']") + |> render_click() + + html = + view + |> element("form[phx-submit='create_cycle']") + |> render_submit(%{"date" => "not-a-date", "amount" => "10"}) + + assert html =~ "Invalid date format" + end end describe "read_only user (Vorstand/Buchhaltung) - no cycle action buttons" do