Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 293394

Simplify exception handling for lazy-load pattern

$
0
0

There are several places in core that use this pattern to implement lazy loading (this snippet from core/lib/Drupal/Core/Batch/BatchStorage.php):

  public function create(array $batch) {
    // Ensure that a session is started before using the CSRF token generator.
    $this->session->start();
    $try_again = FALSE;
    try {
      // The batch table might not yet exist.
      $this->doCreate($batch);
    }
    catch (\Exception $e) {
      // If there was an exception, try to create the table.
      if (!$try_again = $this->ensureTableExists()) {
        // If the exception happened for other reason than the missing table,
        // propagate the exception.
        throw $e;
      }
    }
    // Now that the table has been created, try again if necessary.
    if ($try_again) {
      $this->doCreate($batch);
    }
  }

I think that is a little more complicated than necessary, and I think it is worth cleaning this up, since exception handling should be as transparent as possible. I would like to replace the above code with this, eliminating the $try_again variable:

  public function create(array $batch) {
    // Ensure that a session is started before using the CSRF token generator.
    $this->session->start();
    try {
      // The batch table might not yet exist.
      $this->doCreate($batch);
    }
    catch (\Exception $e) {
      // If there was an exception, then try to create the table.
      if ($this->ensureTableExists()) {
        // Now that the table has been created, try again.
        $this->doCreate($batch);
      }
      else {
        // If the exception happened for other reason than the missing table,
        // then propagate the exception.
        throw $e;
      }
    }
  }

I first noticed this pattern when reviewing #2664322: key_value table is only used by a core service but it depends on system install, but @dawehner pointed out this this pattern is already used elsewhere in core. In that issue, the pattern is slightly different: the foo() method does the work itself, and calls itself from the catch block, instead of having a separate method doFoo() that does the actual work.

I believe that the code is functionally identical, so this should not make any API changes.


Viewing all articles
Browse latest Browse all 293394

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>