diff --git a/CHANGELOG.md b/CHANGELOG.md index 57fb90f6f8..818196c2a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Check the BYOC documentation for more info. ([#1568](https://github.com/Sitecore * `[templates/nextjs]` `[templates/react]` `[templates/vue]` `[templates/angular]` Introduce layout service REST configuration name environment variable ([#1543](https://github.com/Sitecore/jss/pull/1543)) * `[templates/nextjs]` `[sitecore-jss-nextjs]` Support for out-of-process editing data caches was added. Vercel KV or a custom Redis cache can be used to improve editing in Pages and Experience Editor when using Vercel deployment as editing/rendering host ([#1530](https://github.com/Sitecore/jss/pull/1530)) * `[sitecore-jss-react]` Built-in MissingComponent component can now accept "errorOverride" text in props - to be displayed in the yellow frame as a custom error message. ([#1568](https://github.com/Sitecore/jss/pull/1568)) +* `[templates/nextjs]` `[sitecore-jss-nextjs]` Better error handling for component-level data fetching ([#1586](https://github.com/Sitecore/jss/pull/1586)) ### 🧹 Chores diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts index f9a5f56129..6c45ddf35f 100644 --- a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts +++ b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts @@ -1,4 +1,4 @@ -import { ComponentPropsService } from '@sitecore-jss/sitecore-jss-nextjs'; +import { ComponentPropsService, ComponentPropsError } from '@sitecore-jss/sitecore-jss-nextjs'; import { SitecorePageProps } from 'lib/page-props'; import { GetServerSidePropsContext, GetStaticPropsContext } from 'next'; import { moduleFactory } from 'temp/componentBuilder'; @@ -31,6 +31,20 @@ class ComponentPropsPlugin implements Plugin { }); } + const errors = Object.keys(props.componentProps) + .map(id => { + const component = props.componentProps[id] as ComponentPropsError; + + return component.error + ? `\nUnable to get component props for ${component.componentName} (${id}): ${component.error}` + : ''; + }) + .join(''); + + if (errors.length) { + throw new Error(errors); + } + return props; } } diff --git a/packages/sitecore-jss-nextjs/src/index.ts b/packages/sitecore-jss-nextjs/src/index.ts index 2ce900fd4d..906c63c6cb 100644 --- a/packages/sitecore-jss-nextjs/src/index.ts +++ b/packages/sitecore-jss-nextjs/src/index.ts @@ -99,6 +99,7 @@ export { GraphQLRequestClient } from '@sitecore-jss/sitecore-jss'; export { ComponentPropsCollection, + ComponentPropsError, GetStaticComponentProps, GetServerSideComponentProps, } from './sharedTypes/component-props'; diff --git a/packages/sitecore-jss-nextjs/src/services/component-props-service.test.ts b/packages/sitecore-jss-nextjs/src/services/component-props-service.test.ts index c250a00d5a..f0379698bf 100644 --- a/packages/sitecore-jss-nextjs/src/services/component-props-service.test.ts +++ b/packages/sitecore-jss-nextjs/src/services/component-props-service.test.ts @@ -105,7 +105,8 @@ describe('ComponentPropsService', () => { expect(result).to.deep.equal({ x11: 'x11SSRData', x14: { - error: 'Error during preload data for component x14: whoops', + error: 'Error during preload data for component namex14 (x14): whoops', + componentName: 'namex14', }, x16: 'myCustomComponentSSRData', x161: 'myCustomComponentSSRData', @@ -156,7 +157,8 @@ describe('ComponentPropsService', () => { expect(result).to.deep.equal({ x11: 'x11SSRData', x14: { - error: 'Error during preload data for component x14: whoops', + error: 'Error during preload data for component namex14 (x14): whoops', + componentName: 'namex14', }, x16: 'myCustomComponentSSRData', x161: 'myCustomComponentSSRData', @@ -198,7 +200,8 @@ describe('ComponentPropsService', () => { expect(result).to.deep.equal({ x11: 'x11StaticData', x14: { - error: 'Error during preload data for component x14: whoops', + error: 'Error during preload data for component namex14 (x14): whoops', + componentName: 'namex14', }, x16: 'myCustomComponentStaticData', x161: 'myCustomComponentStaticData', @@ -234,7 +237,8 @@ describe('ComponentPropsService', () => { expect(result).to.deep.equal({ x11: 'x11StaticData', x14: { - error: 'Error during preload data for component x14: whoops', + error: 'Error during preload data for component namex14 (x14): whoops', + componentName: 'namex14', }, x16: 'myCustomComponentStaticData', x161: 'myCustomComponentStaticData', diff --git a/packages/sitecore-jss-nextjs/src/services/component-props-service.ts b/packages/sitecore-jss-nextjs/src/services/component-props-service.ts index 13ace2c243..1c07659dbf 100644 --- a/packages/sitecore-jss-nextjs/src/services/component-props-service.ts +++ b/packages/sitecore-jss-nextjs/src/services/component-props-service.ts @@ -182,13 +182,15 @@ export class ComponentPropsService { componentProps[uid] = result; }) .catch((error) => { - const errLog = `Error during preload data for component ${uid}: ${error.message || - error}`; + const errLog = `Error during preload data for component ${ + req.rendering.componentName + } (${uid}): ${error.message || error}`; console.error(chalk.red(errLog)); componentProps[uid] = { error: error.message || errLog, + componentName: req.rendering.componentName, }; }); }); diff --git a/packages/sitecore-jss-nextjs/src/sharedTypes/component-props.ts b/packages/sitecore-jss-nextjs/src/sharedTypes/component-props.ts index 60aaef6aed..1084cd1c5e 100644 --- a/packages/sitecore-jss-nextjs/src/sharedTypes/component-props.ts +++ b/packages/sitecore-jss-nextjs/src/sharedTypes/component-props.ts @@ -1,11 +1,13 @@ import { GetServerSidePropsContext, GetStaticPropsContext } from 'next'; import { ComponentRendering, LayoutServiceData } from '@sitecore-jss/sitecore-jss/layout'; +export type ComponentPropsError = { error: string; componentName: string }; + /** * Shape of component props storage */ export type ComponentPropsCollection = { - [componentUid: string]: unknown; + [componentUid: string]: unknown | ComponentPropsError; }; /**