Problem/Motivation
Discovered while working on #2930028: Comprehensive JSON API integration test coverage phase 1: for every entity type, individual resources only.
http://jsonapi.org/format/#errors contains this:
code: an application-specific error code, expressed as a string value.
The JSON API module does this in \Drupal\jsonapi\Normalizer\HttpExceptionNormalizer::buildErrorObjects()
:
'code' => $exception->getCode(),
If we look that up — http://php.net/manual/en/exception.getcode.php — then we see:
Returns the exception code as integer in Exception but possibly as other type in Exception descendants (for example as string in PDOException).
Sadly, in 99% of cases, this is 0
(an integer) for the JSON API module's errors. Which is misleading.
Proposed resolution
- In
\Drupal\jsonapi\Normalizer\HttpExceptionNormalizer::buildErrorObjects()
, omit'code'
if it is0
, because in that case, no helpful code was specified, so there's no point in exposing it - Update all existing
throw SomeException
code in the JSON API module to contain a helpful code - Add a page in the documentation guide where all the codes are documented. Documentation example of an introduced code: 23: The user is trying to access a restricted field in a related request.
- Result: helpful codes!
OR
- Remove
'code'
from\Drupal\jsonapi\Normalizer\HttpExceptionNormalizer::buildErrorObjects()
altogether - Result: no helpful codes, but also no more misleading.
Remaining tasks
Decide on an approach and execute it.
Comment | File | Size | Author |
---|---|---|---|
#15 | 2934362-15.patch | 1.83 KB | Wim Leers |
|
Comments
Comment #2
Wim LeersComment #3
Wim LeersRelated: #2832211-14: Add source pointer element to "422 Unprocessable Entity" responses, point 4.
Comment #4
e0ipsoDo we need to gate all the bubbled exceptions to provide meaningful errors? I think @gabesullice and I talked about that in some other issue. Maybe we want to conflate the two.
Paging Gabe to know if he remembers the issue where we agreed on that follow up.
Comment #5
Wim LeersI'm not sure I understand what this means — can you elaborate?
Comment #6
e0ipsoThis is the issue were we decided to have a follow-up #2918155: fix(EntityResource|Query\Filter): path validation of filters needs to be aware of computed fields. Note we never did create that issue.
Basically we have some operations in our code that can throw exceptions (for instance saving or deleting an entity or making entity queries). Some of those are bubbling through the exception subscriber. We should catch those exceptions in place and re-throw them as HttpExceptions.
Is it more clear now?
Comment #7
gabesullice@e0ipso @Wim Leers, here is another place where something like this was discussed: #2933615-10: Fix related and relationships endpoints for disabled resources
Basically, there are lower level exceptions that might be thrown (SQL constraint violations, for example). @e0ipso is proposing that we use this issue to more thoroughly map these to low level exceptions to HttpExceptions.
Comment #8
Wim Leers#6+#7: it's clear now, thanks!
What isn't clear yet to me is whether you're both suggesting that each of those
that you're proposing would include that
12345
, where that is a unique code for eachthrow …
occurrence. That's the only way that "code" makes sense.IOW: are you proposing to go with the first or second proposed resolution in the IS?
Comment #9
Ivan Berezhnov CreditAttribution: Ivan Berezhnov as a volunteer and at Drupal Ukraine Community for Levi9 commentedComment #10
e0ipso@Wim Leers yes. I'm proposing to catch all kind of exceptions that may happen (plugin not found, etc.) and re-throw them as the appropriate
SomeHttpException
with a 5xx status code. As part of the same effort we could also add a unique code number to every place we throw an exception… I think that's option 1.Comment #11
Wim Leers👍
Comment #12
Wim LeersUntil we do #10, shouldn't we remove
code
altogether? Right now it's pure noise:code
is always0
. It's information provided to the developer that isn't any information…So I think that rather than waiting for some hypothetical future in which we've done #10 for all relevant JSON API and core code … I think the attached patch is probably a more sensible approach that improves DX today, yet still allows code throwing exceptions to associate a "code" with an exception.
Comment #14
e0ipsoI'm OK having a default of
0
. Removing it may cause unexpected behaviors in clients parsing it. On top of that I think that having a default error code is industry standard. I don't think that conditionally removing it helps DX.In any case I think this is not terribly important either way, so if you feel strongly about this I won't be in the way.
Comment #15
Wim LeersI do feel strongly about it.
(Here's a reroll to update test expectations.)
Comment #16
e0ipsoThat's decided then. Although you need to know that you get a fixed quota on that.
Comment #17
Wim LeersHah :D
I'd much rather have you agreeing with me, so let me try to convince you one more time! :)
It may be an industry standard, but always sending zero is equally helpful as sending a
"number-of-llamas-hurt-while-building-this-response": 0
member.The point of these error codes is that you can look them up in software's knowledgebase and then read a detailed explanation that helps you fix the problem. Drupal doesn't ever set these error codes. It definitely doesn't have a list of such error codes plus accompanying explanations.
For example: https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
I don't understand why you think it doesn't help. It suggests it's a signal, that it's information, but it isn't! Removing pointless information helps developers understand this faster. I would totally have been debugging this, wondering why it's zero, and the answer is …
.My conclusion is: only sending information that is actually relevant helps developers understand errors faster, and prevents them from diving into rabbit holes that may end with them debugging Drupal and hence cursing Drupal/JSON API.
Comment #18
e0ipsoI am good with the change. This is such a minor thing that we should not be typing more into this issue.
Comment #19
e0ipsoPlease move back to Needs Work after merging the initial removal so we can have actually documented codes added in a later patch.
Comment #20
e0ipsoComment #22
e0ipsoMoving back to Needs Work after the merge.
Comment #23
Wim LeersThere have been zero complaints from JSON API users about this change in 2.5 months. IMHO there's nothing left to be done here.
Furthermore, it was stated multiple times by @e0ipso that this is "not terribly important", so rather than keeping this open, I'm closing it. Otherwise this issue will effectively be open forever.