mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: properly rollback transactions on returned errors in generic actions
This commit is contained in:
parent
b8be1123ba
commit
49042b737d
2 changed files with 23 additions and 11 deletions
|
@ -57,8 +57,9 @@ defmodule Ash.Actions.Action do
|
||||||
end
|
end
|
||||||
|
|
||||||
try do
|
try do
|
||||||
|
resources = Enum.reject(resources, &Ash.DataLayer.in_transaction?/1)
|
||||||
|
|
||||||
resources
|
resources
|
||||||
|> Enum.reject(&Ash.DataLayer.in_transaction?/1)
|
|
||||||
|> Ash.DataLayer.transaction(
|
|> Ash.DataLayer.transaction(
|
||||||
fn ->
|
fn ->
|
||||||
case authorize(api, opts[:actor], input) do
|
case authorize(api, opts[:actor], input) do
|
||||||
|
@ -67,12 +68,15 @@ defmodule Ash.Actions.Action do
|
||||||
{:ok, result} ->
|
{:ok, result} ->
|
||||||
{:ok, result, []}
|
{:ok, result, []}
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
Ash.DataLayer.rollback(resources, error)
|
||||||
|
|
||||||
other ->
|
other ->
|
||||||
other
|
raise_invalid_manual_action_return!(input, other)
|
||||||
end
|
end
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
{:error, error}
|
Ash.DataLayer.rollback(resources, error)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
nil,
|
nil,
|
||||||
|
@ -135,13 +139,7 @@ defmodule Ash.Actions.Action do
|
||||||
{:error, error}
|
{:error, error}
|
||||||
|
|
||||||
other ->
|
other ->
|
||||||
raise """
|
raise_invalid_manual_action_return!(input, other)
|
||||||
Invalid return from generic action #{input.resource}.#{input.action.name}.
|
|
||||||
|
|
||||||
Expected {:ok, result} or {:error, error}, got:
|
|
||||||
|
|
||||||
#{inspect(other)}
|
|
||||||
"""
|
|
||||||
end
|
end
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
|
@ -152,6 +150,16 @@ defmodule Ash.Actions.Action do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp raise_invalid_manual_action_return!(input, other) do
|
||||||
|
raise """
|
||||||
|
Invalid return from generic action #{input.resource}.#{input.action.name}.
|
||||||
|
|
||||||
|
Expected {:ok, result} or {:error, error}, got:
|
||||||
|
|
||||||
|
#{inspect(other)}
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
defp authorize(api, actor, input) do
|
defp authorize(api, actor, input) do
|
||||||
input.resource
|
input.resource
|
||||||
|> Ash.Resource.Info.authorizers()
|
|> Ash.Resource.Info.authorizers()
|
||||||
|
|
|
@ -350,7 +350,11 @@ defmodule Ash.DataLayer do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Rolls back the current transaction"
|
@doc "Rolls back the current transaction"
|
||||||
@spec rollback(Ash.Resource.t(), term) :: no_return
|
@spec rollback(Ash.Resource.t() | list(Ash.Resource.t()), term) :: no_return
|
||||||
|
def rollback([resource | _], term) do
|
||||||
|
rollback(resource, term)
|
||||||
|
end
|
||||||
|
|
||||||
def rollback(resource, term) do
|
def rollback(resource, term) do
|
||||||
data_layer(resource).rollback(resource, term)
|
data_layer(resource).rollback(resource, term)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue