Problem/Motivation

Discovered by @alexpott in #3224523: [PHP 8.1] Add ReturnTypeWillChange attribute where necessary, we include DependencySerializationTrait in the JSON API exceptions EntityAccessDeniedHttpException and UnprocessableHttpEntityException. The code has existed since these exceptions were first commited.

However, this seems unnecessary as neither exception stores anything which requires special handling if the exceptions are serialized. @alexpott already proved this does not break tests in #2561915-24: alexpott's test issue.

Steps to reproduce

Proposed resolution

Remove DependencySerializationTrait from the exceptions.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

CommentFileSizeAuthor
#4 3231040-4.patch1.73 KBanul
#10 3231040-revert-10.patch1.73 KBalexpott

Comments

longwave created an issue. See original summary.

alexpott’s picture

longwave’s picture

That commit also added a todo to remove a __sleep() in #2855693: Remove \Drupal\jsonapi\Controller\RequestHandler::renderJsonApiResponse(), add \Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber, which was then done as planned, so I am hopeful this means the use of this trait was obsoleted at the same time.

anul’s picture

Status: Active » Needs review
StatusFileSize
new1.73 KB

Hi Dave,

Removed DependencySerializationTrait from the exceptions EntityAccessDeniedHttpException and UnprocessableHttpEntityException.

Adding a patch for the same.

bbrala’s picture

Status: Needs review » Reviewed & tested by the community

I've reviewed the patch and the linked issues and commit. I don't see any objections why this would result in issues. Setting RTBC, thanks!

catch’s picture

Status: Reviewed & tested by the community » Fixed

Looks like this is redundant, nice find.

Committed 06e7f02 and pushed to 9.3.x. Thanks!

  • catch committed 06e7f02 on 9.3.x
    Issue #3231040 by Anul, longwave, alexpott, bbrala: Remove...
catch’s picture

Issue tags: -Novice

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

alexpott’s picture

Priority: Normal » Critical
Status: Closed (fixed) » Needs review
StatusFileSize
new1.73 KB

This has caused a regression on a client project of mine. JsonAPI access denied requests are failing due to

Exception: LogicException: The database connection is not serializable. This probably means you are serializing an object that has an indirect reference to the database connection. Adjust your code so that is not necessary. Alternatively, look at DependencySerializationTrait as a temporary solution.
Drupal\Core\Database\Connection->__sleep()() (Line: 1993)

This happens because \Drupal\jsonapi\JsonApiResource\ErrorCollection contains exceptions and exceptions have traces and traces have arguments and these can be anything. And if one of these contains a reference to a database we’re done for.

The super super amusing thing is that the only part of the code from DependencySerializationTrait that is necessary is

  /**
   * {@inheritdoc}
   */
  public function __sleep() {
    $vars = get_object_vars($this);
    return array_keys($vars);
  }

because that happens to stop the trace being serialised as the trace is not returned in get_object_vars($this).

This serialisation occurs because \Drupal\jsonapi\EventSubscriber\DefaultExceptionSubscriber::setEventResponse adds all this to the response object which is serialised as part of the page cache.

I think we should revert this change and then turn this into one that adds a test for serializing an exception with a db connection in the trace as part of a cacheable JSON api response.

Here's a patch to prove the revert doesn't break anything.

larowlan’s picture

Status: Needs review » Reviewed & tested by the community
bbrala’s picture

Ok, that was unexpected. Nice one.

  • catch committed 4aa86df on 9.4.x
    Issue #3231040 by alexpott, Anul, longwave, bbrala, catch: (revert)...

  • catch committed afc5a87 on 9.3.x
    Issue #3231040 by alexpott, Anul, longwave, bbrala, catch: (revert)...
catch’s picture

Priority: Critical » Normal
Status: Reviewed & tested by the community » Needs work

Committed/pushed the revert to 9.4.x and 9.3.x.

Restoring this back to old metadata for now.

bbrala’s picture

In order to get this moving forward again we need a few things:

  1. Create a test that tests the regression regarding serializing a database connection.
  2. Define what we need to serialize for an ErrorCollection so we have a clear plan.
  3. Create a new issue (or change the IS) with the new plan on removing trait if we still want this.
alexpott’s picture

@bbrala we will be able to remove the DependencySerializationTrait.

One option is to add ExceptionSerializationTrait which does:

  /**
   * {@inheritdoc}
   */
  public function __sleep() {
    $vars = get_object_vars($this);
    return array_keys($vars);
  }

as this prevents the trace being serialised which is what is causing the problems.

But I think in an ideal world we wouldn't be serialising the exceptions at all. It feels wrong.

longwave’s picture

Shouldn't the page cache contain the already normalized response, instead of all the source objects required to build the response? To me this implies that it's possible that a cached page may be normalized differently (and there is unnecessary work being done) if it is re-normalized every time it is retrieved from cache.

ResourceResponseSubscriber has this note:

    // Run before the dynamic page cache subscriber (priority 100), so that
    // Dynamic Page Cache can cache flattened responses.

but maybe this isn't being run for exception responses?

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.