diff --git a/lib/engine_system/mailbox/mailbox_runtime.ex b/lib/engine_system/mailbox/mailbox_runtime.ex index a09d1e4..b0cb72d 100644 --- a/lib/engine_system/mailbox/mailbox_runtime.ex +++ b/lib/engine_system/mailbox/mailbox_runtime.ex @@ -262,6 +262,7 @@ defmodule EngineSystem.Mailbox.MailboxRuntime do # Execute DSL-defined behaviour patterns defp execute_behaviour(message, state) do + context_meta = message_context(message) # Create proper State.Configuration and State.Environment structures # The behavior evaluation expects these to have local_state fields config_struct = @@ -277,14 +278,16 @@ defmodule EngineSystem.Mailbox.MailboxRuntime do {:ok, effects} -> case apply_effects_to_state(effects, state) do {:ok, updated_state} -> {:ok, effects, updated_state} - {:error, reason} -> {:error, reason} + {:error, reason} -> {:error, {:apply_effects_error, reason, context_meta}} end {:error, reason} -> - {:error, reason} + {:error, {:dsl_evaluation_error, reason, context_meta}} end rescue - exception -> {:error, {:behaviour_error, exception}} + exception -> + meta = safe_message_context(message) + {:error, {:behaviour_exception, exception, __STACKTRACE__, meta}} end # Apply effects to update mailbox state @@ -334,4 +337,57 @@ defmodule EngineSystem.Mailbox.MailboxRuntime do end end) end + + # Build structured metadata from a DSL message payload for better diagnostics + defp message_context(%Message{payload: {op, args}}) when is_atom(op), + do: %{behaviour: op, args: args} + + defp message_context(%Message{payload: op}) when is_atom(op), + do: %{behaviour: op, args: nil} + + defp message_context(%Message{}), do: %{behaviour: :unknown, args: nil} + + defp safe_message_context(message) do + message_context(message) + rescue + _ -> %{behaviour: :unknown, args: nil} + end + + defp format_behaviour_error({:behaviour_exception, exception, stacktrace, meta}) do + op = Map.get(meta, :behaviour, :unknown) + args = Map.get(meta, :args) + + location = + case stacktrace do + [top | _] -> Exception.format_stacktrace_entry(top) + _ -> "unknown" + end + + "- behaviour=#{inspect(op)}\n" <> + " - args=#{inspect(args)}\n" <> + " - error=#{Exception.message(exception)}\n" <> + " - at=#{location}\n" <> + " - meta=#{inspect(meta)}\n" <> + Exception.format_stacktrace(stacktrace) + end + + defp format_behaviour_error({:dsl_evaluation_error, inner, meta}) do + op = Map.get(meta, :behaviour, :unknown) + args = Map.get(meta, :args) + + "- behaviour=#{inspect(op)}\n" <> + " - args=#{inspect(args)}\n" <> + " - reason=#{inspect(inner)}\n" <> + " - meta=#{inspect(meta)}\n" + end + + defp format_behaviour_error({:apply_effects_error, inner, meta}) do + op = Map.get(meta, :behaviour, :unknown) + args = Map.get(meta, :args) + + "- behaviour=#{inspect(op)}\n" <> + " - args=#{inspect(args)}\n" <> + " - apply_effects_error=#{inspect(inner)}\n" <> + " - meta=#{inspect(meta)}\n" + end end