diff --git a/CHANGELOG.md b/CHANGELOG.md index 11f5cfc0ab..85611bbdfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Our versioning strategy is as follows: * `[sitecore-jss-nextjs]` Fix redirects middleware when source URL contains query string. ([#1696](https://github.com/Sitecore/jss/pull/1702)) * `[templates/nextjs-sxa]` Fix feature `show Grid column` in Experience Editor. ([#1704](https://github.com/Sitecore/jss/pull/1704)) * `[templates/nextjs-xmcloud]` Fix double registration of BYOC components ([#1707](https://github.com/Sitecore/jss/pull/1707)) ([#1709](https://github.com/Sitecore/jss/pull/1709)) +* `[sitecore-jss-nextjs] [templates/nextjs-xmcloud]` SDK initialization rejections are now correctly handled. Errors should no longer occur after getSDK() promises resolve when they shouldn't (for example, getting Events SDK in development environment) ([#1712](https://github.com/Sitecore/jss/pull/1712)) ### 🛠 Breaking Changes diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts index 4d23ba17a2..a9faf3d12a 100644 --- a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts +++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/context/sdk/events.ts @@ -6,8 +6,11 @@ const sdkModule: SDK = { init: async (props) => { // Events module can't be initialized on the server side // We also don't want to initialize it in development mode - if (typeof window === 'undefined' || process.env.NODE_ENV === 'development') return; - + if (typeof window === 'undefined') + throw 'Browser Events SDK is not initialized in server context'; + if (process.env.NODE_ENV === 'development') + throw 'Browser Events SDK is not initialized in development environment'; + await Events.init({ siteName: props.siteName, sitecoreEdgeUrl: props.sitecoreEdgeUrl, diff --git a/packages/sitecore-jss-nextjs/src/context/context.test.ts b/packages/sitecore-jss-nextjs/src/context/context.test.ts index 912dd48323..7f1838265e 100644 --- a/packages/sitecore-jss-nextjs/src/context/context.test.ts +++ b/packages/sitecore-jss-nextjs/src/context/context.test.ts @@ -28,6 +28,17 @@ describe('Context', () => { }, }; + const errorSdk = { + Error: { + sdk: { error: 'yes' }, + init: () => { + return new Promise((_, reject) => { + reject('Cannot init Error'); + }); + }, + }, + }; + const fooInitSpy = sinon.spy(sdks.Foo, 'init'); const barInitSpy = sinon.spy(sdks.Bar, 'init'); @@ -159,6 +170,32 @@ describe('Context', () => { expect(context.siteName).to.equal('website-1'); }); + + it('should catch and log when SDK initialization rejects', () => { + const consoleSpy = sinon.spy(console, 'log'); + const localProps = { ...props, sdks: errorSdk }; + const context = new Context(localProps); + context.init(); + expect( + consoleSpy.calledWith('Initialization for SDK Error skipped. Reason: \n Cannot init Error') + ); + consoleSpy.restore(); + }); + + it('should reject when getting SDK that rejected initialization', (done) => { + const localProps = { ...props, sdks: errorSdk }; + const context = new Context(localProps); + context.init(); + context + .getSDK('Error') + .then(() => { + throw new Error('should not resolve'); + }) + .catch((e) => { + expect(e).to.be.equal('Cannot init Error'); + done(); + }); + }); }); describe('getSDK', () => { diff --git a/packages/sitecore-jss-nextjs/src/context/context.ts b/packages/sitecore-jss-nextjs/src/context/context.ts index 61cc0f46d2..93767fbef5 100644 --- a/packages/sitecore-jss-nextjs/src/context/context.ts +++ b/packages/sitecore-jss-nextjs/src/context/context.ts @@ -137,12 +137,17 @@ export class Context { * @returns {void} */ protected initSDK(name: T): void { - this.sdkPromises[name] = new Promise((resolve) => { - this.props.sdks[name].init(this).then(() => { - this.sdks[name] = this.props.sdks[name].sdk; - - resolve(this.sdks[name]); - }); + this.sdkPromises[name] = new Promise((resolve, reject) => { + this.props.sdks[name] + .init(this) + .then(() => { + this.sdks[name] = this.props.sdks[name].sdk; + resolve(this.sdks[name]); + }) + .catch((e) => { + // if init rejects, getSDK will reject too now + reject(e); + }); }); } }