I have two resources that are conceptually related but that I have kept distinct to separately model interface (Front
) concerns and the data layer (Back
) concerns.
defmodule Back do
# Simplified example
use Ash.Resource, data_layer: AshPostgres.DataLayer
attributes do
uuid_primary_key :id
attribute :the_attribute, :string, allow_nil?: false
end
identities do
identity :unique_identity, [:the_attribute]
end
end
defmodule Front do
# Simplified example
use Ash.Resource
attributes do
attribute :the_same_conceptual_attribute, :string
end
end
Is there a way to “stream” errors related to that field from the Back
resource to the Front
resource?
Particularly in this case, how can I pass the allow_nil?
(I know I can duplicate it) and the uniqueness constraints to Front
?
I personally would not separate my resources like that, but that is neither here nor there and I’m sure you have your reasons 
As for modifying the errors, it depends. If the field names are the same then you can generally just return the errors that you get from your Back
resource to your Front
resource.
If not, you will likely need to do some transformation. This is just a shot in the dark, but is an example of remapping field names. We can potentially add helpers to do this sort of thing, but honestly the concept of mapping “any error that X operation can produce” into “some error that makes sense for Y operation” is one of the hardest problems in programming in my experience 
case Back.do_thing() do
{:error, error_class} ->
{:error, %{error_class | errors: Enum.map(errors, &transform_error/1)}}
{:ok, result} ->
{:ok, result}
end
defp transform_error(error) do
error
|> transform_field()
|> transform_fields()
end
defp transform_field(%{field: field} = error) do
%{error | field: remap_field(field)}
end
defp transform_fields(%{fields: fields} = error) do
%{error | fields: Enum.map(fields, &remap_field/1)}
end
defp remap_field(:foo), do: :some_conceptual_foo
defp remap_field(:bar), do: :some_conceptual_bar
defp remap_field(field), do: field