Skip to content

User defined exception of class: :forbidden is swallowed by default implementation #366

@pcapel

Description

@pcapel

Code of Conduct

  • I agree to follow this project's Code of Conduct

AI Policy

  • I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.

Versions

Erlang/OTP 27 [erts-15.2.7] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]
Elixir 1.18.4 (compiled with Erlang/OTP 27)
ash_json_api 1.4.38

Operating system

MacOS

Current Behavior

Attempting to create an implementation for an application specific error will not succeed if the Splode.Error class given is :forbidden.

The only real example here is to define an exception in accordance with the docs and observe that you're receiving a generic forbidden error instead of what you're trying to create.

Reproduction

You should be able to verify it by attempting to create your own error and return if from an endpoint:

defmodule MyApp.Forbidden.NoSoupForYou do
  @moduledoc false
  use Ash.Error.Exception
  use Splode.Error, fields: [], class: :forbidden

  @impl Exception
  def message(_error) do
    "The request could not be processed because NO SOUP FOR YOU!"
  end

  defimpl AshJsonApi.ToJsonApiError do
    @spec to_json_api_error(term) :: AshJsonApi.Error.t() | list(AshJsonApi.Error.t())
    def to_json_api_error(error) do
      %AshJsonApi.Error{
        id: Ash.UUID.generate(),
        status_code: 403,
        code: "no_soup_for_you",
        title: "No Soup For You Error",
        detail: error.message
      }
    end
  end
end

This is roughly the implementation that I found this on, and changing the class specified to e.g. :invalid gives the expected error.

Expected Behavior

I'm not entirely sure. This seems intentional, but I would have either expected a warning, or that the implementation was respected. The issue seems to be an explicit pattern match on the :forbidden class:

def to_json_api_errors(_domain, _resource, %{class: :forbidden} = error, _type) do
[
%__MODULE__{
id: Ash.UUID.generate(),
status_code: class_to_status(error.class),
code: "forbidden",
title: "Forbidden",
detail: "forbidden"
}
]
end

I'm happy to work through a PR to address this in whatever fashion is desirable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Someday

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions