Problem/Motivation
JSON:API responds with a 500 error on the resource list when a referenced entity is deleted without removing the reference from the resource.
Steps to reproduce with a default Drupal 8.6.10, JSON:API 2.3 and JSON:API Extras 3.4 installation (latest):
- Have a content type, e.g. Article with a taxonomy reference field, e.g. field_tag referencing Tag taxonomy terms
- Overwrite JSON:API settings and change the alias of field_tag to something else, e.g. field_tag_alias
- Create an Article and choose a Tag
- Delete the Tag taxonomy term that is referenced, but do not remove it from the Article
- Visit /jsonapi/node/article and get a 500 error with the following message
Error: Call to a member function getTypeName() on boolean in Drupal\jsonapi\JsonApiResource\ResourceIdentifier->__construct() (line 79 of modules/contrib/jsonapi/src/JsonApiResource/ResourceIdentifier.php).
Drupal\jsonapi\JsonApiResource\ResourceIdentifier->__construct(, 'missing', Array) (Line: 450)
Drupal\jsonapi\JsonApiResource\ResourceIdentifier::getVirtualOrMissingResourceIdentifier(Object) (Line: 282)
Drupal\jsonapi\JsonApiResource\ResourceIdentifier::toResourceIdentifier(Object) (Line: 315)
Drupal\jsonapi\JsonApiResource\ResourceIdentifier::toResourceIdentifiers(Object) (Line: 52)
Drupal\jsonapi\Normalizer\EntityReferenceFieldNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 58)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array)
call_user_func_array(Array, Array) (Line: 67)
Drupal\jsonapi_extras\SerializerDecorator->relay('normalize', Array) (Line: 102)
Drupal\jsonapi_extras\SerializerDecorator->normalize(Object, 'api_json', Array) (Line: 95)
Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->serializeField(Object, Array, 'api_json') (Line: 55)
Drupal\jsonapi\Normalizer\ResourceObjectNormalizer->normalize(Object, 'api_json', Array) (Line: 37)
Drupal\jsonapi_extras\Normalizer\ResourceObjectNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 61)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 253)
Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer->Drupal\jsonapi\Normalizer\{closure}(Object)
array_map(Object, Array) (Line: 254)
Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer->normalizeEntityCollection(Object, 'api_json', Array) (Line: 182)
Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer->normalize(Object, 'api_json', Array) (Line: 143)
Symfony\Component\Serializer\Serializer->normalize(Object, 'api_json', Array) (Line: 58)
Drupal\jsonapi\Serializer\Serializer->normalize(Object, 'api_json', Array)
call_user_func_array(Array, Array) (Line: 67)
Drupal\jsonapi_extras\SerializerDecorator->relay('normalize', Array) (Line: 102)
Drupal\jsonapi_extras\SerializerDecorator->normalize(Object, 'api_json', Array) (Line: 115)
Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber->renderResponseBody(Object, Object, Object, 'api_json') (Line: 80)
Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber->onResponse(Object, 'kernel.response', Object)
call_user_func(Array, Object, 'kernel.response', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.response', Object) (Line: 191)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 173)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 41)
Drupal\jsonapi\StackMiddleware\FormatSetter->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Proposed resolution
I think it has something to do with \Drupal\jsonapi\ResourceType\ResourceType::getRelatableResourceTypesByField() not being overriden in \Drupal\jsonapi_extras\ResourceType\ConfigurableResourceType.
Remaining tasks
Discussion, Patch, etc.
User interface changes
None expected.
API changes
None expected.
Data model changes
None expected.
Release notes snippet
None expected.
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | interdiff-3035544-8-10.txt | 2.01 KB | br0ken |
| #10 | 3035544-10.patch | 3.17 KB | br0ken |
Comments
Comment #2
ndobromirov commented+1 here.
I've managed to reproduce this.
Comment #3
ndobromirov commentedComment #4
e0ipsoThis looks like a good candidate to have an automated test for.
Comment #5
Raman Starshykh commentedComment #6
Andrei_tab commentedHi there. This issue is more related to the cores entity_refefence
Here is the issue that will solve the same problems.
Entity reference isEmpty() fix.
Comment #7
linichalexey commentedComment #8
br0kenThis is the failing test case for #3034786: ResourceIdentifier::getVirtualOrMissingResourceIdentifier() ignores field aliases; causes $relatable_resource_types field to be empty and results in an error.
Comment #10
br0kenComment #12
br0kenSetting to NR since tests were passed (have no idea why it's red while there are only deprecation warnings).
Comment #13
ndobromirov commentedMaybe CI builds do not approve of deprecated APIs being used?
Comment #14
br0kenI think this is because of a custom
drupalci.ymlI've added to the patch. The important thing here is that tests were passed with the patch applied. The bug is injsonapibut connected to resources renaming so tests could be written only using this project. So this issue will be automatically resolved altogether with #3034786: ResourceIdentifier::getVirtualOrMissingResourceIdentifier() ignores field aliases; causes $relatable_resource_types field to be empty and results in an error.Comment #15
wim leers#3034786: ResourceIdentifier::getVirtualOrMissingResourceIdentifier() ignores field aliases; causes $relatable_resource_types field to be empty and results in an error landed in Drupal 9.0 and 8.9 some time ago and earlier today it also landed in 8.8.
So: as soon as you update to Drupal 8.8 this will be gone :)