Skip to content

Commit

Permalink
Merge pull request #1712 from Sitecore/bug/jss-1396-handle-missing-sdk
Browse files Browse the repository at this point in the history
[sitecore-jss-nextjs] Reject getSDK promise when SDK init was rejected
  • Loading branch information
art-alexeyenko authored and addy-pathania committed Jan 17, 2024
1 parent 45966ad commit a550c0e
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ const sdkModule: SDK<typeof Events> = {
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,
Expand Down
37 changes: 37 additions & 0 deletions packages/sitecore-jss-nextjs/src/context/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ describe('Context', () => {
},
};

const errorSdk = {
Error: {
sdk: { error: 'yes' },
init: () => {
return new Promise<void>((_, reject) => {
reject('Cannot init Error');
});
},
},
};

const fooInitSpy = sinon.spy(sdks.Foo, 'init');
const barInitSpy = sinon.spy(sdks.Bar, 'init');

Expand Down Expand Up @@ -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<typeof errorSdk>(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<typeof errorSdk>(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', () => {
Expand Down
17 changes: 11 additions & 6 deletions packages/sitecore-jss-nextjs/src/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,17 @@ export class Context<SDKModules extends SDKModulesType> {
* @returns {void}
*/
protected initSDK<T extends keyof SDKModules>(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);
});
});
}
}

0 comments on commit a550c0e

Please sign in to comment.