rbino

rbino

Ash Core Team

Some context to avoid the XY Problem: I’m trying to expose some state which lives in an external API as a resource field.

Let’s say I have a User resource and I want to retrieve the URL for their Gravatar given their email. My understanding is that I can do this with a calculation

  calculations do
    calculate :gravatar_url, :string, User.Calculations.Gravatar
  end
defmodule MyApp.User.Calculations.Gravatar do
  use Ash.Calculation
  alias MyApp.GravatarAPI

  def calculate(users, _opts, _context) do
    Enum.map(users, fn user ->
      case GravatarAPI.fetch_url(user.email) do
        {:ok, url} -> url
        {:error, _} -> nil
      end
    end)
  end
end

The problem with this solution is that if I retrieve a list of users using, e.g., GraphQL, the current implementation just silently returns nil without letting the user know that, e.g., the API request failed for a specific user (which is something which can potentially be shown in GraphQL errors).

On the other hand, if I return {:error, :something} if anything fails a single failed API request makes the calculation fails for all the users.

Is there a way around this? Am I using the wrong Ash tool?

The other possibility I thought of is using a resource with no data layer instead of a calculation. n that case, if I call both Simple.set_data and Ash.Query.add_error does the whole query fails (so nothing gets exposed from GraphQL) or is the partial data shown alongside the error?

Showing Posts 1 to 4

zachdaniel

zachdaniel

Creator of Ash

This is a good question :). While I think there is something we could do in the future to make this more seamless, if you have a calculation that can partially fail, the best way to do it is to use an embedded type for the return type.

calculate :gravatar_url, :map, User.Calculations.Gravatar do
  constraints fields:  [
    success: [
      type: :boolean,
      allow_nil?: false
    ],
    url: [
      type: :string,
    ]
  ]  
end
rbino

rbino OP

Ash Core Team

Thanks, this is indeed an interesting way to go.

I still have to explore how AshGraphql exposes errors, and see if I can expose an error in the retrieval from the API in a similar way

zachdaniel

zachdaniel

Creator of Ash

Yeah…honestly this is probably something that we should add as a feature of calculations, so that calculations should be allowed to fail. Fail-able calculations would have something like field: %Ash.CalculationResult{result: "result", errors: []}. Then AshGraphql could use that :slight_smile:

zachdaniel

zachdaniel

Creator of Ash

The recent refactor of calculation loading would likely make this a relatively simple thing to support, but it would take some time/effort still.

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews