Repository: vercel/next.js
File: test/e2e/app-dir/errors/index.test.ts (TypeScript)

Code before:
           "at __next_root_layout_boundary__",
           "at RedirectErrorBoundary",
           "at RedirectBoundary",
           "at HTTPAccessFallbackErrorBoundary",
           "at HTTPAccessFallbackBoundary",
           "at DevRootHTTPAccessFallbackBoundary",
           "at AppDevOverlayErrorBoundary",
           "at HotReload",
           "at Router",
           "at ErrorBoundaryHandler",
           "at ErrorBoundary",
           "at RootErrorBoundary",
           "at AppRouter",
           "at ServerRoot",
           "at Root",
         ]
        `)

        expect(
          normalizeComponentStack(
            await browser.elementByCss('#error-owner-stack').text()
          )
        ).toMatchInlineSnapshot(`
          [
            "at ErrorBoundary",
            "at OuterLayoutRouter",
          ]
        `)
      }
    })

    // production tests
    if (isNextStart) {
      it('should allow resetting error boundary', async () => {
        const browser = await next.browser('/client-component')

        // Try triggering and resetting a few times in a row
        for (let i = 0; i < 5; i++) {
          await browser
            .elementByCss('#error-trigger-button')
            .click()
            .waitForElementByCss('#error-boundary-message')

          expect(
            await browser.elementByCss('#error-boundary-message').text()
          ).toBe('An error occurred: this is a test')

          await browser
            .elementByCss('#reset')
            .click()
            .waitForElementByCss('#error-trigger-button')

Review comment (suggestion):
This isn't the owner stack we want. we want the owner stack of the component that errored. We should talk to Sebbie about where to call this so we get the right stack

Code after:

        expect(output).toContain(`digest: '${digest}'`)
      })

      it('should log the original Server Actions error trace in production', async () => {
        const logIndex = next.cliOutput.length
        const browser = await next.browser('/server-actions')
        // trigger server action
        await browser.elementByCss('#button').click()
        // wait for response
        let digest
        await retry(async () => {
          digest = await browser.waitForElementByCss('#digest').text()
          expect(digest).toMatch(/\d+/)
        })

        const output = stripAnsi(next.cliOutput.slice(logIndex))
        // Log the original rsc error trace
        expect(output).toContain('Error: server action test error')
        // Does not include the react renderer error for server actions
        expect(output).not.toContain(
          'Error: An error occurred in the Server Components render'
        )
        expect(output).toContain(`digest: '${digest}'`)
      })
    }

    describe('unstable_retry', () => {
      afterEach(async () => {
        // Always restore __nextTestRecover so it doesn't leak between tests
        await next.fetch('/server-component/recover/set-recover?enabled=false')
      })

      it('should recover Server Component error after unstable_retry', async () => {
        const browser = await next.browser('/server-component/recover')

        expect(
          await browser.elementByCss('#error-boundary-message').text()
        ).toBe(
          isNextDev
            ? 'this is a test'
            : 'An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.'
        )

        // Enable recovery via globalThis.__nextTestRecover
        await next.fetch('/server-component/recover/set-recover')

        await browser
          .elementByCss('#retry')
          .click()
          .waitForElementByCss('#recover')