Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic pages with query in layout can fail silently, causing hard-to-debug errors during generate #2682

Open
garyo opened this issue Jul 1, 2024 · 11 comments

Comments

@garyo
Copy link

garyo commented Jul 1, 2024

Environment

  • Operating System: Darwin
  • Node Version: v18.13.0
  • Nuxt Version: 3.12.2
  • CLI Version: 3.12.0
  • Nitro Version: 2.9.7
  • Package Manager: [email protected]
  • Builder: -
  • User Config: devtools, modules, routeRules
  • Runtime Modules: @nuxt/[email protected], @nuxt/[email protected]
  • Build Modules: -

Reproduction

Minimal reproducer is at https://github.com/garyo/nuxt-bug-report1
To repro, clone that repo, pnpm install, and pnpm generate (or use yarn/npm). You will see errors.

Describe the bug

This example shows a hard-to-debug issue with Nuxt content query and SSR static site generation.

The problem is that the dynamically generated pages/articles/tags/[tag].vue page slug, use the NuxtLayout default layout. That layout runs a content query in a script:

const route = useRoute()
const { data: page } = await useAsyncData(`content-${route.path}-layout`,
                                          () => queryContent().where({ _path: route.path}).findOne())

const parentPath = computed(
  () => {
    const pathArr = route.path.split('/') // e.g. ["", "articles", "article1"]
    pathArr.pop() // remove last component
    if (pathArr.length <= 1)
      return '/'
    return pathArr.join('/')
  }
)

For some reason, that script causes the prerender to fail silently, such that those dynamically rendered tags pages return 404s (or actually the pre-generated query results return 404s):

Errors prerendering:
  ├─ /api/_content/query/SzZjDQLhN0.1719800696160.json (3ms)                                          nitro 10:25:00 PM
  │ ├── Error: [404] Document not found!
  │ └── Linked from /articles/tags/blog
  ├─ /api/_content/query/qq4agTT8na.1719800696160.json (2ms)                                          nitro 10:25:00 PM
  │ ├── Error: [404] Document not found!
  │ └── Linked from /articles/tags
  ├─ /api/_content/query/KhUI7un7Nu.1719800696160.json (0ms)                                          nitro 10:25:00 PM
  │ ├── Error: [404] Document not found!
  │ └── Linked from /articles

The fix is to have the dyamic pages use a simpler layout that doesn't do this query. But the bug I'm reporting is that the failures during prerender are silent (except for the 404s reported above) so it is very nearly impossible to debug. Took me many hours to even find out it was the layout that was responsible. It seems likely the query is failing but the error is silently discarded; it would be much better if the actual failure were reported when it happens, so the developer can see what query failed with a pointer to their file & line number.

Additional context

No response

Logs

No response

@farnabaz
Copy link
Member

farnabaz commented Jul 9, 2024

You can enable nitro.prerender.failOnError in Nuxt config to break the generation is some error occurs

export default defineNuxtConfig({
  nitro: {
    prerender: {
      failOnError: true
    }
  }
})

@garyo
Copy link
Author

garyo commented Jul 12, 2024

Thanks for that, @farnabaz -- I just tried it in the test project linked above, and unfortunately it does not show any new errors or tracebacks or anything helpful at all. I still just get the unexplained 404s during pnpm generate.

@farnabaz
Copy link
Member

As I checked your content, Seems that you have some links to non-existed pages in your content. You have a lint to /articles/tags/blog page, but there is no blog.md file inside /content/articles directory. That's why generation is failing

@garyo
Copy link
Author

garyo commented Jul 16, 2024

That's a tag; the tag pages are auto-generated by pages/articles/tags/[tag].vue. That works fine locally, but not when generating.

Copy link
Member

Indeed it is a tag, but inside layout you are trying to fetch the content based on the route.path but in case of /tags/* pages, there is no matched content and that leads to 404 error and generation fail.
You can create two create two different layouts, one for articles and other for tags

@garyo
Copy link
Author

garyo commented Jul 16, 2024

Indeed it is a tag, but inside layout you are trying to fetch the content based on the route.path but in case of /tags/* pages, there is no matched content and that leads to 404 error and generation fail. You can create two create two different layouts, one for articles and other for tags

Yes, I think you are right -- as I mentioned in the bug report:

The fix is to have the dynamic pages use a simpler layout that doesn't do this query.

But the reason I created this bug report is that it is nearly impossible to figure out what needs to be done based on the error messages shown during generate (at least for me, not a nuxt expert). Especially since the whole site works fine in pnpm dev mode with no 404s. As you can see, the 404s mentioned in the generate step are anonymous queries. Perhaps a Nuxt expert can parse those errors and understand what needs to be done, but for a "normal" person a stack trace showing the query itself, or the source line of the query (which is in the layout), would have saved me multiple days.

My hope is that by showing this example, someone could trap the error at a better place and show something useful to help users.

@farnabaz
Copy link
Member

My hope is that by showing this example, someone could trap the error at a better place and show something useful to help users.

Perhaps the module could log some warnings in the console in Dev mode to warn about generation issue.

@garyo
Copy link
Author

garyo commented Jul 16, 2024

Yes, that might help -- but I don't actually see anything wrong in dev mode; there the query seems to work ok (at least it does not throw; maybe it's returning an empty result?)

@farnabaz
Copy link
Member

If you look at the network tab in dev mode you will find 404 api calls. In generation, module tries to generate those api calls which results 404 error and fail in generation.

@garyo
Copy link
Author

garyo commented Jul 16, 2024

Ah, I see what you mean. It clearly points to default.vue here. Yes, it would be most excellent if these errors were shown during nuxt generate!
image

@cailliaud
Copy link

cailliaud commented Jul 23, 2024

I have the same issue with some malformed markdown content and it is really annoying because the continuous integration (gitlab-ci) does not detect that the generate command had errors ....
The build is considered successfull even if the static bundle at the end contains nothing because of nuxt content error during the prerender phase...

yarn run v1.22.22
$ nuxt generate
[...]
[success] Server built in 113ms
[info] [nitro] Initializing prerenderer
[info] [nitro] Prerendering 9 initial routes with crawler
[log] [nitro]   ├─ /__sitemap__/style.xsl (119ms)
[log] [nitro]   ├─ /en (387ms)
[log] [nitro]   ├─ /fr (382ms)
[log] [nitro]   ├─ /200.html (348ms)
[log] [nitro]   ├─ /404.html (329ms)
[log] [nitro]   ├─ /index.html (283ms)
[error] [unhandledRejection] can not read a block mapping entry; a multiline key may not be an implicit key (6:1)
  at generateError (node_modules/js-yaml/dist/js-yaml.mjs:1273:10)
  at throwError (node_modules/js-yaml/dist/js-yaml.mjs:1277:9)
  at readBlockMapping (node_modules/js-yaml/dist/js-yaml.mjs:2235:9)
  at composeNode (node_modules/js-yaml/dist/js-yaml.mjs:2531:12)
  at readDocument (node_modules/js-yaml/dist/js-yaml.mjs:2715:3)
  at loadDocuments (node_modules/js-yaml/dist/js-yaml.mjs:2778:5)
  at Object.load$1 [as load] (node_modules/js-yaml/dist/js-yaml.mjs:2804:19)
  at parseFrontMatter (node_modules/remark-mdc/dist/index.mjs:46:21)
  at .nuxt/prerender/chunks/runtime.mjs:2587:50
  at parseMarkdown (.nuxt/prerender/chunks/runtime.mjs:2610:10)
Done in 49.17s.

I tried the nitro prerender config in nuxt.config.ts but the CI still passed.

I saw that in previous version of Nuxt (V2) there was a command arg --fail-on-error (V2 doc) maybe it could be great to have it on Nuxt V3 and V4 (so it could be an issue for Nuxt main project ?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants