Verified Commit 72d9d9ba authored by Jess's avatar Jess
Browse files

Issue #3175449 by mfb, super_romeo, smustgrave, _pratik_, Medha Kumari, Nitin...

Issue #3175449 by mfb, super_romeo, smustgrave, _pratik_, Medha Kumari, Nitin shrivastava, quietone, alexpott, xjm, dagmar, longwave: Display backtrace for logged throwables on log message details page

(cherry picked from commit d5e06105)
parent 245659c6
Loading
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -291,6 +291,12 @@ public function eventDetails($event_id) {
        ['data' => ['#markup' => $dblog->link]],
      ],
    ];
    if (isset($dblog->backtrace)) {
      $rows[] = [
        ['data' => $this->t('Backtrace'), 'header' => TRUE],
        $dblog->backtrace,
      ];
    }
    $build['dblog_table'] = [
      '#type' => 'table',
      '#rows' => $rows,
@@ -350,6 +356,10 @@ protected function buildFilterQuery(Request $request) {
   *   The record from the watchdog table. The object properties are: wid, uid,
   *   severity, type, timestamp, message, variables, link, name.
   *
   *   If the variables contain a @backtrace_string placeholder which is not
   *   used in the message, the formatted backtrace will be assigned to a new
   *   backtrace property on the row object which can be displayed separately.
   *
   * @return string|\Drupal\Core\StringTranslation\TranslatableMarkup|false
   *   The formatted log message or FALSE if the message or variables properties
   *   are not set.
@@ -372,6 +382,10 @@ public function formatMessage($row) {
          $variables['@backtrace_string'] = new FormattableMarkup(
            '<pre class="backtrace">@backtrace_string</pre>', $variables
          );
          // Save a reference so the backtrace can be displayed separately.
          if (!str_contains($row->message, '@backtrace_string')) {
            $row->backtrace = $variables['@backtrace_string'];
          }
        }
        $message = $this->t(Xss::filterAdmin($row->message), $variables);
      }
+30 −0
Original line number Diff line number Diff line
@@ -142,6 +142,36 @@ public function testLogEventPage() {
    $this->assertSession()->pageTextContains('Notice');
  }

  /**
   * Tests that the details page displays the backtrace for a logged \Throwable.
   */
  public function testOnError(): void {
    // Log in as the admin user.
    $this->drupalLogin($this->adminUser);

    // Load a page that throws an exception in the controller, and includes its
    // function arguments in the exception backtrace.
    $this->drupalGet('error-test/trigger-exception');

    // Load the details page for the most recent event logged by the "php"
    // logger.
    $query = Database::getConnection()->select('watchdog')
      ->condition('type', 'php');
    $query->addExpression('MAX([wid])');
    $wid = $query->execute()->fetchField();
    $this->drupalGet('admin/reports/dblog/event/' . $wid);

    // Verify the page displays a dblog-event table with a "Type" header.
    $table = $this->assertSession()->elementExists('xpath', "//table[@class='dblog-event']");
    $type = "//tr/th[contains(text(), 'Type')]/../td";
    $this->assertSession()->elementsCount('xpath', $type, 1, $table);

    // Verify that the backtrace row exists and is HTML-encoded.
    $backtrace = "//tr//pre[contains(@class, 'backtrace')]";
    $this->assertCount(1, $table->findAll('xpath', $backtrace));
    $this->assertSession()->responseContains('&lt;script&gt;alert(&#039;xss&#039;)&lt;/script&gt;');
  }

  /**
   * Tests that a 403 event is logged with the exception triggering it.
   */
+9 −1
Original line number Diff line number Diff line
@@ -68,9 +68,17 @@ public function generateFatals() {

  /**
   * Trigger an exception to test the exception handler.
   *
   * @param string $argument
   *   A function argument which will be included in the exception backtrace.
   *
   * @throws \Exception
   */
  public function triggerException() {
  public function triggerException(string $argument = "<script>alert('xss')</script>"): void {
    define('SIMPLETEST_COLLECT_ERRORS', FALSE);
    // Add function arguments to the exception backtrace.
    ini_set('zend.exception_ignore_args', FALSE);
    ini_set('zend.exception_string_param_max_len', 1024);
    throw new \Exception("Drupal & awesome");
  }