ash-project / ash-project/ash_json_api
Allow better customization of error status
- Dominant language
- Elixir
- Stars
- 94
- Forks
- 80
- Avg merge
- 5h 5m
- Merged PRs (30d)
- 4
Description
In #276 I mentioned adding `409` for uniqueness violations.
Similarly, my current implementation returns `422` instead of `400` when there are validation errors on user data. Much internet blood has been spilled over what's the appropriate error here and personally, I don't care beyond too much about the esoteric points.
1. `400` is valid.
2. `422` is valid.
The problem for me moving to Ash is... I currently use `422` and can't break my clients.
I use `422` mainly because I have a background in Rails _and_ because I think differentiating the body validation errors improves the "ergonomics" of the API. When my clients get back `422` as the main HTTP status they know it's a validation issue on their body content. Whereas I return a `400` for all errors related to the query parameters. It gives the client a sort of "resolve this mess first" way of looking at multiple errors.
I feel like I need two things to make this happen:
1. Obviously, a way to assign certain errors or classes of error to a particular status code.
2. A way to define a precedence of which error code is returned when there are multiple errors in a response.
Lemme explain the second a bit. In this [example from the JSON:API](https://jsonapi.org/examples/#error-objects-multiple-errors) site itself they show `status` showing up multiple times. I really dislike this example because... you can only return _one_ status. In my own implementation the code gives a more general guideline of the primary error and then the actual `code` attribute is what the client should care about.
It's totally possible to, in a single request, do things that might trigger many different errors:
1. An identity conflict (`409` in my world)
2. A validation error because the type is wrong on some attribute (`422` in my world)
3. Something in the sparse fields that's wrong, so a query param error (`400` in my world)
4. Trying to associate a relationship in a cross tenant way (`403` in my world - and I explicitly return a 403 because sometimes implementations that cross multiple tenants get really confused if I say "sorry, that's not a thing" rather than "hey, that's a real thing and your user can definitely see it but it's totally not allowed here")
The actual HTTP code is returned is going to be a `409` here for me and it would resolve thusly depending on the errors: `409` -> `403` -> `400` -> `422`.
So that's what I would like. To do so that I would need to be able to do two things:
1. Map HTTP status explicitly to certain errors/error types. I'm actually not familiar enough with Ash errors to make this happen, but identity problems validation errors like any other in the changeset, so being able to override would probably require semi-complex configuration.
2. Set an explicit precedence for which HTTP status to return.
I'm fine building the stuff, but before I dive I need a guidance on convention and wouldn't shrug off some advice on where to begin.
# Ensure there's a way to produce `409` responses when an identity conflict occurs
We discussed this in the other ticket, but there's not much more to say. We just need to make sure the above is able to ultimately return a `409` if any of the errors are the result of an identity validation problem (including the primary key).
Contributor guide
Assessment
This issue has not been assessed yet.