sst / open-next

Open source Next.js serverless adapter
https://open-next.js.org
MIT License
3.7k stars 111 forks source link

Unexpected token ] in JSON when trying to deploy to SST #371

Closed tseppl closed 4 months ago

tseppl commented 4 months ago

I am trying to deploy a NextJs site, which works locally when running "npm run dev" and also build succeeds by running "npm run build", but fails when running "npx sst deploy".

It seems there are a few extra characters in the end of the JSON - specifically ]}

Here is the excerpt from terminal (some info obfuscated or stripped):

npx sst deploy --stage prod
SST v2.38.3

➜  App:     sst-next
   Stage:   prod
   Region:  eu-west-1
   Account: 1234567890123

Next.js v14.0.4
OpenNext v2.3.1

┌─────────────────────────────────┐
│ OpenNext — Building Next.js app │
└─────────────────────────────────┘

> sst-next@0.1.0 build
> next build

   ▲ Next.js 14.0.4
   - Environments: .env

 ✓ Creating an optimized production build
 ✓ Compiled successfully
 ✓ Linting and checking validity of types
 ✓ Collecting page data
 ✓ Generating static pages (5/5)
 ✓ Collecting build traces
 ✓ Finalizing page optimization

Route (app)                              Size     First Load JS
┌ λ /                                    1.22 kB         106 kB
├ ○ /_not-found                          0 B                0 B
├ λ /[slug]                             1.22 kB         106 kB
├ λ /[slug]/[type]                     1.22 kB         106 kB
└ λ /[slug]/[type]/[id]             176 B            87 kB
+ First Load JS shared by all            81.8 kB
  ├ chunks/938-97f845deaffc21a2.js       26.7 kB
  ├ chunks/fd9d1056-ea4f02c0a4383bef.js  53.3 kB
  ├ chunks/main-app-8265353934748fac.js  220 B
  └ chunks/webpack-c27cd9c8c8d6140c.js   1.64 kB

ƒ Middleware                             135 kB

○  (Static)   prerendered as static content
λ  (Dynamic)  server-rendered on demand using Node.js

┌──────────────────────────────┐
│ OpenNext — Generating bundle │
└──────────────────────────────┘

Bundling static assets...
Bundling cache assets...
undefined:1
{
"kind":"FETCH",
"data":{
"headers":{
"access-control-allow-headers":"X-Access-Token, access_token, X-Requested-With, Content-Type, Accept, Origin, Authorization",
"access-control-allow-methods":"GET, POST, PUT, DELETE, OPTIONS",
"access-control-allow-origin":"*",
"cf-cache-status":"DYNAMIC",
"cf-ray":"855d2389sasb518-OLA",
"connection":"keep-alive",
"content-encoding":"br",
"content-language":"fi",
"content-type":"application/json",
"date":"Thu, 15 Feb 2024 12:29:02 GMT",
"nel":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}","report-to":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.b.com\\/report\\/v3?s=XfFTW5szfRV%2B7%2FQzxkoiwWak32dscJmgLVLoj7Hyh0SBHED7Zrwm0f6riQoml3H4DPi1DxXzsVsVas8a73OMbrCd36QONZdwUVQXXqNBepSVI54Ri%2Fq7QQWOqqskTTg%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}","server":"b","transfer-encoding":"chunked","vary":"Accept-Encoding"
},
"body":"W3sic3RhdHVzIjoiZm9yc2FsZSIU3RhbXAudWxsLCJpc...thiscontentisstripped...015RmF2b3JpdGUiOm51bGwsImlzSGlkZGVuQWQiOm51bGx9XQ==",
"status":200,
"url":"https://api.hidden.dev/rest/items/search?page=1&rows=30"},
"revalidate":31536000,
"tags":[]
}]}

SyntaxError: Unexpected token ] in JSON at position 201187
    at JSON.parse (<anonymous>)
    at file:///Users/t/.npm/_npx/5e5e2f11d04ee7cb/node_modules/open-next/dist/build.js:363:39
    at file:///Users/t/.npm/_npx/5e5e2f11d04ee7cb/node_modules/open-next/dist/build.js:651:13
    at Array.forEach (<anonymous>)
    at traverseFiles (file:///Users/t/.npm/_npx/5e5e2f11d04ee7cb/node_modules/open-next/dist/build.js:644:51)
    at createCacheAssets (file:///Users/t/.npm/_npx/5e5e2f11d04ee7cb/node_modules/open-next/dist/build.js:361:13)
    at build (file:///Users/t/.npm/_npx/5e5e2f11d04ee7cb/node_modules/open-next/dist/build.js:31:9)
conico974 commented 4 months ago

We do not modify the fetch cache entry, so if the JSON is incorrect the issue is coming from next itself. It might not appear as an issue in next because if it throws an exception while loading this cache item, it will consider that the item is not cached and refetch. We could add a try catch block around the JSON.parse() during build to catch this error, but it won't solve the underlying issue. Could you try with next@14.1 and open-next@2.3.5 ?

khuezy commented 4 months ago

This looks like an error at build time, can you log the json data of the fetch request on the page?

tseppl commented 4 months ago

After adding try/catch blocks around different parts of the application it seems that the page was not able to render because of https://nextjs.org/docs/messages/dynamic-server-error and will produce this error also during "npm run build", so the error is not open-next related.

Jdruwe commented 2 months ago

We are also experiencing the same issue, triggering another build works most of the time. In our case we are getting an extra curly bracket at the end. Will also try and see if this is caused by some other issue first.

Jdruwe commented 2 months ago

@tseppl I also added some try catch blocks but it's not logging anything. Bundling cache assets only start after successfully generating static pages so I wonder where you added your try catch statements. Note that I am not getting any error when running the regular next build (non open-next) locally.

tseppl commented 2 months ago

@Jdruwe

For me "npm run build" would not produce any errors before adding the try catch blocks and this was ultimately also the reason why I thought it was an issue with open-next. After adding try catch blocks around fetch json parse the build would finally fail with Dynamic Server Error.

I think Dynamic Server Error usually originates from trying to render the page statically but using dynamic resources such as headers, cookies, searchparams etc which are only available during client runtime.

Jdruwe commented 2 months ago

@tseppl Thanks for the response,

  1. What do you exactly mean by "After adding try catch blocks around fetch json parse". I am trying to find the correct place to add the try catch statement, I assume you added it to your own code and not the code provided by open-next?
  2. What the open-next build failing every time for you? As In my case it isn't which makes this even more strange.
tseppl commented 2 months ago

I have to admit I cannot remember all the details anymore but try adding a try catch block around where you fetch data inside your components. Also if you try to access things like cookies etc. This way you will at least get an error displayed.


try {
  const response = await fetch('https://website');
} catch (error) {
  // TypeError: Failed to fetch
  console.log('There was an error', error);
}

I think there is some problems with consistency with this setup. So sometimes you have to delete the .next dir manually and then run build again. Some cache won't clear itself for some reason at times. To get a consistent result you can write a script that first deletes the .next dir and then starts the build.