Recursion, with block and error handling question

Hello.
I have some questions about recursion and error handling.
For example…
I want to send email to multiple client using like this.

def send_message([head_address | tail_address], message, from_email) do
    with {:ok, result} <- Message.send(head_address,message, from_email) do
      {:ok, result}
    else
      {:error, reason} -> {:error, reason}
    end
    
    send_message(tail_address, message, from_email)
  end
  
  def send_message([], _message, _from_email), do: :done

what if any one of email is incorrect or delivery fails, Message,send return {:error, reason}, but how can I send or keep error message while using recursion? so end of loop, I want to get a message something like how many errors occured and what error message is.

Please Help :frowning:

add it as a param you pass to the recursion

so

def send_mail([head_address | tail_address], message, from_email, result_arr) do

where result map could be a map of the results or an array like follows

[%{email: a_users_email, result: {:ok, result} or {:error, reason}}]

and then on the base case:

def send_message(, _message, _from_email,result_arr), do: result_map

1 Like

I’d also like to point out that the type of recursion you are doing might be replaced by more higher-level abstractions like the Enum module:

defmodule ExampleMailSending do
  def send_messages(addresses, message, from_email) do
    addresses
    |> Enum.map(&Message.send(&1, message, from_email))
    |> Enum.group_by(&elem(&1, 0)) # Splits results into successes and failures for easy introspection
  end
end

Another notice: What type of data structure is ‘Message’? It might make sense to separate (the logic of properly constructing/manipulating) the data structure from the logic of sending it somewhere.

3 Likes

Thanks for the good idea!

1 Like

Thanks for your answer.!

Message is Struct

1 Like