next.js icon indicating copy to clipboard operation
next.js copied to clipboard

feat: modified notFound() to throw new NotFound()

Open wyattjoh opened this issue 3 years ago • 4 comments
trafficstars

Bug

  • [ ] Related issues linked using fixes #number
  • [ ] Integration tests added
  • [ ] Errors have a helpful link attached, see contributing.md

Feature

  • [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
  • [ ] Related issues linked using fixes #number
  • [ ] Integration tests added
  • [ ] Documentation added
  • [ ] Telemetry added. In case of a feature if it's used or not.
  • [ ] Errors have a helpful link attached, see contributing.md

Documentation / Examples

  • [ ] Make sure the linting passes by running pnpm lint
  • [ ] The "examples guidelines" are followed from our contributing doc

wyattjoh avatar Oct 25 '22 03:10 wyattjoh

Failing test suites

Commit: fcb2495f66b658603d7cabe64c2270917efbd27e

pnpm testheadless test/integration/relay-analytics/test/index.test.js

  • Analytics relayer with exported method > reports attribution
Expand output

● Analytics relayer with exported method › reports attribution

TypeError: Cannot read properties of null (reading 'find')

  141 |     )
  142 |     const metrics = JSON.parse(str)
> 143 |     const LCP = metrics.find((m) => m.name === 'LCP')
      |                         ^
  144 |     expect(LCP).toBeDefined()
  145 |     expect(LCP.attribution).toBeDefined()
  146 |     expect(LCP.attribution.element).toBe('#__next>div>h1')

  at Object.<anonymous> (integration/relay-analytics/test/index.test.js:143:25)

Read more about building and testing Next.js in contributing.md.

ijjk avatar Oct 25 '22 03:10 ijjk

What's this for?

sebmarkbage avatar Oct 25 '22 05:10 sebmarkbage

Was briefly exploring an alternative syntax of:

import { NotFound } from 'next/navigation';

const User = async () => {
  const user = await getUser();
  if (!user) {
    throw new NotFound();
  }

  return <div>{user.name}</div>;
}

Instead of:

import { notFound } from 'next/navigation';

const User = async () => {
  const user = await getUser();
  if (!user) {
    throw notFound();
  }

  return <div>{user.name}</div>;
}

Because technically, notFound() already throws, I thought it might be more ergonomic to construct the error directly and throw that. This also avoids the typescript errors we see when instead of throwing, we return, as void isn't a valid return type from a component.

Open to ideas to resolve this, but as it stands, I don't feel as though it's a very good developer experience.

wyattjoh avatar Oct 26 '22 17:10 wyattjoh

I believe we can type notFound() and redirect() with the return type : never.

That way this should work without type errors:

import { notFound } from 'next/navigation';

const User = async () => {
  const user = await getUser();
  if (!user) {
    notFound();
  }

  return <div>{user.name}</div>;

That way you don't have to return nor throw.

sebmarkbage avatar Oct 26 '22 18:10 sebmarkbage

The : never change was implemented.

timneutkens avatar Dec 16 '22 13:12 timneutkens