blitz-js / blitz

⚡️ The Missing Fullstack Toolkit for Next.js

Home Page:https://Blitzjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Update `NotFoundError` to work with react server components

tordans opened this issue · comments

What do you want and why?

I have a queries/getRegions.ts that says if (!region) throw new NotFoundError().
I have a page server component ShowRegionPage() in the app directory that should handle the happy path. And a not-found.tsx on level up that should handle the 404 case.

What I want to happen is, that a throw new NotFoundError in a invoked action renders the not-found page.

What happens is some non-helpfull error:

image

I assume that maybe Blitz needs to modify what the NotFoundError returns?

Research

The NextJS docs are no help in how to trigger the 404 case https://nextjs.org/docs/app/api-reference/file-conventions/not-found.

I could not find recent discussion on the topic in the NextJS Github sources.

Possible implementation(s)


Blitz version: 2.0.0-beta.34 (local)
macOS Ventura | darwin-arm64 | Node: v19.2.0


 Package manager: npm

  System:
    OS: macOS 13.6
    CPU: (8) arm64 Apple M1
    Memory: 105.30 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 19.2.0 - ~/.nvm/versions/node/v19.2.0/bin/node
    Yarn: Not Found
    npm: 8.19.3 - ~/.nvm/versions/node/v19.2.0/bin/npm
  npmPackages:
    @blitzjs/auth: 2.0.0-beta.34 => 2.0.0-beta.34
    @blitzjs/next: 2.0.0-beta.34 => 2.0.0-beta.34
    @blitzjs/rpc: 2.0.0-beta.34 => 2.0.0-beta.34
    @prisma/client: 5.5.2 => 5.5.2
    blitz: 2.0.0-beta.34 => 2.0.0-beta.34
    next: 13.5.6 => 13.5.6
    prisma: 5.5.2 => 5.5.2
    react: 18.2.0 => 18.2.0
    react-dom: 18.2.0 => 18.2.0
    typescript: 4.9.5 => 4.9.5

@tordans, you can use the latest release v2.0.0-beta.35 that will help with this use case

// blitz-server.ts
import { notFound } from "next/navigation"
...
RpcServerPlugin({
  onInvokeError(error) {
    if(error instanceof NotFoundError) {
      notFound()
    }
  },
}),

The feature is documented in the release notes
I will update the website docs with the latest changes early tomorrow.

@tordans I am closing this issue. Let me know if you face any issues and we can reopen. Thanks for the issue!

@siddhsuresh that sounds perfect. Unfortunately I am missing something…

Do I still need to manually return an error code from the query like documented in

if (!user) {
const userError = new NotFoundError("User not found")
return {
error: userError.statusCode,
}
?

The error message did not change from what I screenshotted above.

My Code:

Do I assumed that I use import { notFound } from 'next/navigation' for notFound and that this import will take care to find the right file in my app directory?

Thanks for the help!

Hey I do not think you upgraded to the latest beta, this feature is introduced in v35 and I think you are still in v34. Can you recheck?

image

@siddhsuresh you are right, I only updated blitz 🤦 . All is .35 now FixMyBerlin/atlas-app@81cdc06

However, I still see the issue for http://127.0.0.1:5173/regionen/foo

Status:

 ✓ Compiled /regionen/[regionSlug]/page in 7s (3469 modules)
2023-10-31 11:18:46.041	INFO	[blitz-invoke]	getPublicRegion() Starting with input: {
  slug: 'foo'
}
2023-10-31 11:18:46.201	INFO	[blitz-invoke]	getPublicRegion() Starting with input: {
  slug: 'foo'
}
aaa NotFoundError: This could not be found
    at eval (webpack-internal:///(rsc)/./src/regions/queries/getPublicRegion.ts:33:24) {
  statusCode: 404
}
aaa NotFoundError: This could not be found
    at eval (webpack-internal:///(rsc)/./src/regions/queries/getPublicRegion.ts:33:24) {
  statusCode: 404
}
 ✓ Compiled /icon.svg/route in 1344ms (2118 modules)
 ✓ Compiled (2149 modules)
2023-10-31 11:18:48.927	INFO	[blitz-rpc]	getCurrentUser() Starting with input: null
2023-10-31 11:18:48.928	DEBUG	[blitz-rpc]	getCurrentUser() Result: null
2023-10-31 11:18:48.929	DEBUG	[blitz-rpc]	getCurrentUser() Next.js serialization:1ms
2023-10-31 11:18:48.929	INFO	[blitz-rpc]	getCurrentUser() Finished: resolver:1ms serializer:1ms total:2ms
2023-10-31 11:18:48.957	INFO	[blitz-rpc]	getPublicRegion() Starting with input: {
  slug: 'foo'
}
[NotFoundError: This could not be found] { statusCode: 404 }
2023-10-31 11:18:48.964	ERROR	[blitz-rpc]	getPublicRegion()

 Error  NotFoundError: This could not be found
error stack:
  • index-server.cjs	RpcLogger.error
	/node_modules/@blitzjs/rpc/dist/index-server.cjs:184
  • index-server.cjs
	/node_modules/@blitzjs/rpc/dist/index-server.cjs:520
  •

  • index-server.cjs	rejected
	/node_modules/@blitzjs/rpc/dist/index-server.cjs:373

@tordans okay, before I actually have to clone your repo and give it a try. Can you try calling the invoke in the page component along with the generateMetdata function (Maybe vercel/next.js#49925 (comment) ?)

export default function ShowRegionPage() {
  await invoke(getPublicRegion, { slug: params.regionSlug })
  return (
    <MapInterfaceInitialization>
      <MapInterface />
    </MapInterfaceInitialization>
  )
}

ShowRegionPage.authenticate = false

Also regarding ShowRegionPage.authenticate = false here I am pretty sure it does not work in the app router. Does it?

You can use useAuthenticatedAppSession hook for this

If it does work, then it would be better to cache this response and reuse the response in both, since AFAIK the resolver is not using ctx

Still no luck @siddhsuresh

  • Adding the invoke call to the page does not help
  • Removing the metadata does not help
  • Removing my custom components does not help
  • All of those together does not help…

I updated the test app that I created to showcase #4232 with the not-found case.

thanks for the update @tordans will take a look at your setup tomorrow and let you know

@siddhsuresh FYI my testcase and comment is updated above