I’ve been using generic actions lately but when they need to return {:error, whatever}
things go a bit haywire. Remembering something about Splode from the changelogs I attempted to create custom errors for my application, following the get started with splode guide.
That produces errors that seem to do the right thing, but when a generic action returns {:error, %MyApp.Errors.CustomError{...}}
I get a different error.
The following reproduces it:
Mix.install(
[
{:ash, "~> 3.0"}
],
consolidate_protocols: false
)
defmodule Accounts.Errors do
use Splode, error_classes: [
invalid: Accounts.Errors.Invalid,
unknown: Accounts.Errors.Unknown,
custom: Accounts.Errors.Custom
],
unknown_error: Accounts.Errors.Unknown.Unknown
end
defmodule Accounts.Errors.Custom do
use Splode.ErrorClass, class: :custom
end
defmodule Accounts.Errors.CustomError do
use Splode.Error, fields: [:thing, :message], class: :custom
def message(%{thing: thing, message: message}) do
"Custom error for #{thing}: #{message}"
end
end
defmodule Accounts.Profile do
use Ash.Resource,
domain: Accounts,
data_layer: Ash.DataLayer.Ets
actions do
defaults [:read, :destroy, :create, :update]
action :fun, :term do
run fn _, _ ->
{:error, Accounts.Errors.CustomError.exception(thing: "city hall", message: "really has gone to pot")}
end
end
end
end
defmodule Accounts do
use Ash.Domain, validate_config_inclusion?: false
resources do
resource Accounts.Profile do
define :fun
end
end
end
err = Accounts.Errors.CustomError.exception(thing: "city hall", message: "gone to pot")
IO.inspect(err, label: "error at toplevel")
IO.puts("error from generic action")
Accounts.fun()
# $ elixir ash_error_issue.ex
# error at toplevel: %Accounts.Errors.CustomError{
# thing: "city hall",
# message: "gone to pot",
# splode: nil,
# bread_crumbs: [],
# vars: [],
# path: [],
# stacktrace: #Splode.Stacktrace<>,
# class: :custom
# }
# error from generic action
# ** (UndefinedFunctionError) function nil.exception/1 is undefined
# nil.exception([errors: [%Accounts.Errors.CustomError{thing: "city hall", message: "really has gone to pot", splode: Ash.Error, bread_crumbs: [], vars: [], path: [], stacktrace: #Splode.Stacktrace<>, class: :custom}], splode: Ash.Error])
# (ash 3.0.9) /home/.../elixir-1.16.2-erts-14.0.2/11d33faefc03b6705b27e772a36495ef/deps/splode/lib/splode.ex:211: Ash.Error.to_class/2
# (ash 3.0.9) lib/ash/error/error.ex:66: Ash.Error.to_error_class/2
# (ash 3.0.9) lib/ash.ex:1306: Ash.run_action/2
# ash_error_issue.ex:64: (file)