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

fix(runtime): throw RUNTIME-008 Error when script resources load failed #3348

Merged
merged 8 commits into from
Dec 27, 2024

Conversation

danpeen
Copy link
Contributor

@danpeen danpeen commented Dec 12, 2024

Description

fix(runtime): In order for users to receive resource loading errors, throw RUNTIME-008 Error when script resources load failed

Related Issue

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have updated the documentation.

Copy link

changeset-bot bot commented Dec 12, 2024

🦋 Changeset detected

Latest commit: e1c3af4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 27 packages
Name Type
@module-federation/error-codes Patch
@module-federation/runtime Patch
@module-federation/sdk Patch
@module-federation/dts-plugin Patch
website-new Patch
@module-federation/devtools Patch
@module-federation/data-prefetch Patch
@module-federation/nextjs-mf Patch
@module-federation/node Patch
@module-federation/retry-plugin Patch
@module-federation/runtime-tools Patch
@module-federation/webpack-bundler-runtime Patch
@module-federation/bridge-react Patch
@module-federation/bridge-vue3 Patch
@module-federation/enhanced Patch
@module-federation/esbuild Patch
@module-federation/managers Patch
@module-federation/manifest Patch
@module-federation/modern-js Patch
@module-federation/rsbuild-plugin Patch
@module-federation/rspack Patch
@module-federation/storybook-addon Patch
@module-federation/utilities Patch
@module-federation/bridge-react-webpack-plugin Patch
@module-federation/modernjsapp Patch
@module-federation/third-party-dts-extractor Patch
@module-federation/bridge-shared Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

netlify bot commented Dec 12, 2024

Deploy Preview for module-federation-docs ready!

Name Link
🔨 Latest commit e1c3af4
🔍 Latest deploy log https://app.netlify.com/sites/module-federation-docs/deploys/676e5d04e95d5b00081a55c9
😎 Deploy Preview https://deploy-preview-3348--module-federation-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@squadronai squadronai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This pull request introduces a fix to improve error handling when script resources fail to load. The key changes are:

  • Throw a specific RUNTIME-008 error when script resources fail to load, providing users with more informative error messages.
  • In the SDK, the createScript function now accepts an onErrorCallback option, which is called when a script fails to load. Additionally, the timeout duration for script loading has been increased from 20 seconds to 60 seconds.
  • These changes aim to enhance the overall user experience by giving them more detailed information when script resource loading issues occur, helping them better identify and resolve such problems.
File Summaries
File Summary
packages/runtime/src/utils/load.ts The code changes introduce a new error handling mechanism to throw a specific RUNTIME-008 error when script resources fail to load. This ensures that users receive more informative error messages when encountering resource loading issues.
packages/sdk/src/dom.ts The code changes introduce an error handling mechanism for script resource loading failures. The createScript function now accepts an onErrorCallback option, which is called when a script fails to load. Additionally, the timeout duration for script loading has been increased from 20 seconds to 60 seconds. These changes aim to provide users with more detailed error information when script resources fail to load.

@danpeen danpeen changed the title fix: throw RUNTIME-008 Error when script resources load failed fix(runtime): throw RUNTIME-008 Error when script resources load failed Dec 12, 2024
Copy link
Contributor

@squadronai squadronai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incremental Review

Comments posted: 6

Configuration

Squadron Mode: essential

Commits Reviewed

3ae535306492443fc17066a1d778dad9ad5939eb...4d840084169876e812336cd983c0047724c9a854

Files Reviewed
  • packages/runtime/src/utils/load.ts
  • packages/sdk/src/dom.ts
Files Ignored

These files were ignored due to the filter in the squadron.yaml file.

  • .changeset/smart-crabs-burn.md
  • packages/error-codes/src/desc.ts
  • packages/error-codes/src/error-codes.ts

Comment on lines 132 to 141
.catch((e) => {
// const errMsg = getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
// remoteName: name,
// remoteEntryUrl: entry,
// });
assert(
undefined,
getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
remoteName: name,
resourceUrl: entry,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling here can be improved. Currently, you're asserting undefined which will always trigger the error, then throwing the original error. This creates two error messages and makes debugging harder. Instead, create a custom error with the formatted message:

Suggested change
.catch((e) => {
// const errMsg = getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
// remoteName: name,
// remoteEntryUrl: entry,
// });
assert(
undefined,
getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
remoteName: name,
resourceUrl: entry,
.catch((e) => {
const errorMsg = getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
remoteName: name,
resourceUrl: entry,
});
throw new Error(errorMsg);
});

This approach:

  1. Creates a single, clear error message
  2. Preserves the error context
  3. Is more efficient than asserting and throwing separately

Comment on lines 132 to 141
.catch((e) => {
// const errMsg = getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
// remoteName: name,
// remoteEntryUrl: entry,
// });
assert(
undefined,
getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
remoteName: name,
resourceUrl: entry,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error type checking to provide more specific error messages for different failure scenarios. For example, network errors might need different handling than syntax errors in the loaded script:

Suggested change
.catch((e) => {
// const errMsg = getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
// remoteName: name,
// remoteEntryUrl: entry,
// });
assert(
undefined,
getShortErrorMsg(RUNTIME_008, runtimeDescMap, {
remoteName: name,
resourceUrl: entry,
.catch((e) => {
const details = {
remoteName: name,
resourceUrl: entry,
errorType: e instanceof Error ? e.name : 'Unknown',
};
const errorMsg = getShortErrorMsg(RUNTIME_008, runtimeDescMap, details);
throw new Error(errorMsg);
});

Comment on lines 94 to 98
clearTimeout(timeoutId);
const onScriptCompleteCallback = () => {
if (event.type === 'error') {
info?.cb?.reject && info?.cb?.reject(event);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic should throw a specific error code (RUNTIME-008) as mentioned in the PR title. Currently, it's just passing the error to the callback. Modify the error handling to:

Suggested change
clearTimeout(timeoutId);
const onScriptCompleteCallback = () => {
if (event.type === 'error') {
info?.cb?.reject && info?.cb?.reject(event);
} else {
if (event.type === 'error') {
const error = new Error(`Failed to load script: ${info.url}`);
error.code = 'RUNTIME-008';
info?.onErrorCallback && info?.onErrorCallback(error);
} else {
info?.cb && info?.cb();
}

Comment on lines 199 to 203
// eslint-disable-next-line @typescript-eslint/no-explicit-any
event: any,
): void => {
const onLinkCompleteCallback = () => {
if (event.type === 'error') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the script error handling, the link error handling should also use the RUNTIME-008 error code:

Suggested change
// eslint-disable-next-line @typescript-eslint/no-explicit-any
event: any,
): void => {
const onLinkCompleteCallback = () => {
if (event.type === 'error') {
if (event.type === 'error') {
const error = new Error(`Failed to load link: ${info.url}`);
error.code = 'RUNTIME-008';
info?.onErrorCallback && info?.onErrorCallback(error);
} else {
info?.cb && info?.cb();
}

cb?: {
resolve: (value: void | PromiseLike<void>) => void;
reject: (error: Error) => void;
};
attrs?: Record<string, any>;
needDeleteScript?: boolean;
createScriptHook?: CreateScriptHookDom;
}): { script: HTMLScriptElement; needAttach: boolean } {
// Retrieve the existing script element by its src attribute
let script: HTMLScriptElement | null = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout value should be configurable through the info parameter rather than hardcoded. Consider adding a timeout option to the info parameter interface.

packages/sdk/src/dom.ts Show resolved Hide resolved
Copy link
Contributor

@squadronai squadronai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incremental Review

Comments posted: 5

Configuration

Squadron Mode: essential

Commits Reviewed

3ae535306492443fc17066a1d778dad9ad5939eb...df9adea20c412b2b828d64aa7c4a4fd7142ec6b0

Files Reviewed
  • packages/runtime/src/utils/load.ts
  • packages/sdk/src/dom.ts
Files Ignored

These files were ignored due to the filter in the squadron.yaml file.

  • .changeset/smart-crabs-burn.md
  • packages/error-codes/src/desc.ts
  • packages/error-codes/src/error-codes.ts

packages/runtime/src/utils/load.ts Show resolved Hide resolved
attrs?: Record<string, any>;
needDeleteScript?: boolean;
createScriptHook?: CreateScriptHookDom;
}): { script: HTMLScriptElement; needAttach: boolean } {
// Retrieve the existing script element by its src attribute
let script: HTMLScriptElement | null = null;
let needAttach = true;
let timeout = 20000;
let timeout = 60000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout value should be declared as a const since it's not being reassigned within the scope. Consider: ```suggestion
const timeout = 60000;

Comment on lines 94 to 98
if (event.type === 'error') {
info?.onErrorCallback && info?.onErrorCallback(event);
} else {
info?.cb && info?.cb();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optional chaining operator (?.) is used redundantly with the && operator. Simplify to: ```suggestion
if (event.type === 'error') {
info.onErrorCallback?.(event);
} else {
info.cb?.();
}

Comment on lines 199 to 203
if (event.type === 'error') {
info?.onErrorCallback && info?.onErrorCallback(event);
} else {
info?.cb && info?.cb();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the script handler, simplify the optional chaining: ```suggestion
if (event.type === 'error') {
info.onErrorCallback?.(event);
} else {
info.cb?.();
}

Comment on lines 244 to 246
attrs: {
fetchpriority: 'high',
...attrs,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fetchpriority attribute should be included in the TypeScript interface definition for attrs to ensure type safety. Consider documenting why high priority is needed as a default.

@steven-pribilinskiy
Copy link

steven-pribilinskiy commented Dec 16, 2024

just my 2 cents, I would suggest to make RUNTIME errors more memorable and move from the RUNTIME-XXX naming to RUNTIME_SHORTDESCR

In this case, e.g. RUNTIME_RESLOAD

wdyt?

@zhoushaw zhoushaw merged commit 4fd33fb into main Dec 27, 2024
16 checks passed
@zhoushaw zhoushaw deleted the feat/create-script-reject branch December 27, 2024 08:15
@2heal1 2heal1 mentioned this pull request Dec 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants