ash-project / ash_json_api

The JSON:API extension for the Ash Framework
https://hexdocs.pm/ash_json_api
MIT License
63 stars 43 forks source link

Missing Field Name in Error Response When Setting Up AshJsonApi with Generic Actions #191

Open diogomrts opened 5 months ago

diogomrts commented 5 months ago

Describe the bug When I try to setup AshJsonApi with a generic action, if there are required arguments it returns an error but without the field name:

image

To Reproduce With a simple Ash.Resource and a route like this:

defmodule App.Core.Test do
  use Ash.Resource,
    domain: App.Core,
    extensions: [
      AshJsonApi.Resource,
    ]

  json_api do
    type "test"

    routes do
      base("/test")

      route(:get, "/:id/data", :read_data)
    end
  end

  resource do
    require_primary_key? false
  end

  attributes do
    attribute :name, :string, public?: true
  end

  actions do
    action :read_data, :struct do
      argument :id, :uuid, allow_nil?: false
      argument :name, :string, allow_nil?: false

      run fn input, context ->
        input.arguments.name
      end
    end
  end
end

Expected behavior The field seems to be missing because the error structure is like this:

[(ash_json_api 1.3.1) lib/ash_json_api/error/error.ex:279: AshJsonApi.ToJsonApiError.Ash.Error.Changes.Required.to_json_api_error/1]
error #=> %Ash.Error.Changes.Required{
  field: :campaign_id,
  type: :argument,
  resource: Calleebree.Core.Widget,
  splode: Ash.Error,
  bread_crumbs: [],
  vars: [],
  path: [],
  stacktrace: #Splode.Stacktrace<>,
  class: :invalid
}

but the implementation for the error is looking for error.vars and not error.field

image

diogomrts commented 1 week ago

I just encountered an issue that I'm not sure is related to this when adding a new POST route pointing to a generic ation. In this generic action with a required string argument:

action :submit do
  argument :contact_name, :string, allow_nil?: false

  run fn %Ash.ActionInput{} = input, context ->
    dbg("action")
  end
end

If we pass an empty string in the body of the POST request it will throw this error:

16:13:26.240 [error] ** (Ash.Error.Invalid)
Invalid Error

* argument contact_name is required
  (ash 3.4.41) lib/ash/error/changes/required.ex:4: Ash.Error.Changes.Required.exception/1
  (ash 3.4.41) lib/ash/action_input.ex:158: anonymous fn/2 in Ash.ActionInput.require_arguments/1
  (elixir 1.17.3) lib/enum.ex:2531: Enum."-reduce/3-lists^foldl/2-0-"/3

Which results in this same error as described above:

{
  "errors": [
    {
      "code": "required",
      "id": "4ec324c9-ab23-464d-aa02-018396a7c301",
      "meta": {},
      "status": "400",
      "title": "Required",
      "detail": "is required"
    }
  ],
  "jsonapi": {
    "version": "1.0"
  }
}

Setting the request field to null in the json body results in a proper error message:

image

zachdaniel commented 6 days ago

Really need to get around to this one. Sorry its been so long :)