From a550c0ef6ff1720352b6762bd424975217874073 Mon Sep 17 00:00:00 2001 From: Artem Alexeyenko Date: Fri, 12 Jan 2024 17:17:57 -0500 Subject: [PATCH] Merge pull request #1712 from Sitecore/bug/jss-1396-handle-missing-sdk [sitecore-jss-nextjs] Reject getSDK promise when SDK init was rejected --- CHANGELOG.md | 1 + .../src/lib/context/sdk/events.ts | 7 +++- .../src/context/context.test.ts | 37 +++++++++++++++++++ .../src/context/context.ts | 17 ++++++--- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd27cb8066..4bd8ba4685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Our versioning strategy is as follows: * `[templates/nextjs]` `[sitecore-jss-nextjs]` Fix making a fetch to a nextjs api route in an editing environment, by adding additional variable publicUrl in runtime config ([#1656](https://github.com/Sitecore/jss/pull/1656)) * `[templates/nextjs-multisite]` Fix site info fetch errors (now skipped) on XM Cloud rendering/editing host builds. ([#1649](https://github.com/Sitecore/jss/pull/1649)) ([#1653](https://github.com/Sitecore/jss/pull/1653)) * `[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); + }); }); } }