diff --git a/lib/mv/membership_fees/cycle_generator.ex b/lib/mv/membership_fees/cycle_generator.ex index f87961a..bc68c44 100644 --- a/lib/mv/membership_fees/cycle_generator.ex +++ b/lib/mv/membership_fees/cycle_generator.ex @@ -142,7 +142,15 @@ defmodule Mv.MembershipFees.CycleGenerator do |> Task.async_stream(fn member -> {member.id, generate_cycles_for_member(member, today: today)} end) - |> Enum.map(fn {:ok, result} -> result end) + |> Enum.map(fn + {:ok, result} -> + result + + {:exit, reason} -> + # Task crashed - log and return error tuple + Logger.error("Task crashed during cycle generation: #{inspect(reason)}") + {nil, {:error, {:task_exit, reason}}} + end) end defp build_results_summary(results) do @@ -298,7 +306,7 @@ defmodule Mv.MembershipFees.CycleGenerator do end defp create_cycles(cycle_starts, member_id, fee_type_id, amount) do - cycles = + results = Enum.map(cycle_starts, fn cycle_start -> attrs = %{ cycle_start: cycle_start, @@ -314,15 +322,16 @@ defmodule Mv.MembershipFees.CycleGenerator do end end) - errors = Enum.filter(cycles, &match?({:error, _}, &1)) + {successes, errors} = Enum.split_with(results, &match?({:ok, _}, &1)) + successful_cycles = Enum.map(successes, fn {:ok, cycle} -> cycle end) if Enum.empty?(errors) do - {:ok, Enum.map(cycles, fn {:ok, cycle} -> cycle end)} + {:ok, successful_cycles} else Logger.warning("Some cycles failed to create: #{inspect(errors)}") - # Return successfully created cycles anyway - successful = Enum.filter(cycles, &match?({:ok, _}, &1)) |> Enum.map(fn {:ok, c} -> c end) - {:ok, successful} + # Return partial failure with both successful and failed cycles + # This allows callers to decide how to handle partial failures + {:error, {:partial_failure, successful_cycles, errors}} end end end