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 invoke
d action renders the not-found
page.
What happens is some non-helpfull error:
![image](https://private-user-images.githubusercontent.com/111561/279109139-cbfb920c-8f16-4763-aff0-a147a0df23aa.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDQ2MzYyNjQsIm5iZiI6MTcwNDYzNTk2NCwicGF0aCI6Ii8xMTE1NjEvMjc5MTA5MTM5LWNiZmI5MjBjLThmMTYtNDc2My1hZmYwLWExNDdhMGRmMjNhYS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwMTA3JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDEwN1QxMzU5MjRaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT05MDVlMzViMmY0MGU2MjBlMjI5YjU1NDM4MTU3MTY3MmJkN2NjYmVmNDMxOGM5NGY2NmNiZjJhNWYzYWMyZmM1JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.2P5F-ON3ABb6QMqkv5v2aZeVhv6S_YtWJOduRK1rogA)
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
blitz/packages/blitz-next/README.md
Lines 350 to 354 in fb232d1
The error message did not change from what I screenshotted above.
My Code:
- I added it to FixMyBerlin/atlas-app@074faa1
But I never see theaaa
log in my console. - The way I throw is https://github.com/FixMyBerlin/atlas-app/blob/blitz-app-directory/src/regions/queries/getPublicRegion.ts#L27
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!
@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:
- I now see my console log "aaa"
- The Error is the same as in my initial screenshot
- This is my blitz-server.ts
- This is the page I am rendering, which should 404
- This is the not-found page I expect (one folder level up but not the top level not-found)
✓ 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.
-
http://localhost:3000/foo => ✔️ shows the right not-found
-
http://localhost:3000/users/1/projects/foo => 🔴 has the same error I have in our app, documented above
This is a client component usinguseQuery
-
http://localhost:3000/projects/foo => 🔴 "Unhandled Runtime Error Error: This could not be found"
This is a server component usinginvoke
from@blitzjs/rpc
andgetProject
has noresolver.authorize()
.- Page
- Same Query getProject.ts
-
http://localhost:3000/projects-session-error/foo => 🔴 "Unhandled Runtime Error
Error: Cannot read properties of undefined (reading 'session')"
This is a server component usinginvoke
from@blitzjs/rpc
andgetProjectSessionError
has the regularresolver.authorize()
.
This issue is likely unrelated and sounds more like #4242 (comment)
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