mirror of
https://github.com/toeverything/AFFiNE.git
synced 2025-01-09 04:10:09 +03:00
fix(core): global error handler should be registered outside webpack runtime (#8556)
This commit is contained in:
parent
db374f7feb
commit
1ed9775c45
@ -1,5 +1,4 @@
|
||||
// ORDER MATTERS
|
||||
import './global-error-handler';
|
||||
import './env';
|
||||
import './public-path';
|
||||
import './polyfill/browser';
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB |
@ -1,81 +0,0 @@
|
||||
/* eslint-disable no-var */
|
||||
import errorImg from './error.png';
|
||||
|
||||
var errorEl: HTMLDivElement | null = null;
|
||||
function showGlobalErrorPage() {
|
||||
if (errorEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
errorEl = document.createElement('div');
|
||||
errorEl.innerHTML = [
|
||||
'<style>',
|
||||
'.gue {display:flex;flex-direction:column;align-items:center;justify-content:center;width:380px;}',
|
||||
'.gue img{width:380px;}',
|
||||
'.gue div{padding:16px 40px 0 40px;text-align:center;}',
|
||||
'.gue .p1{color:#141414;line-height:24px;font-weight:500;}',
|
||||
'.gue .p2{color:#7A7A7A;line-height:22px;}',
|
||||
'</style>',
|
||||
'<div class="gue">',
|
||||
'<img src="',
|
||||
errorImg,
|
||||
'" />',
|
||||
'<div>',
|
||||
'<p class="p1">Unsupported Environment</p>',
|
||||
'<p class="p2">',
|
||||
'It looks like AFFiNE cannot run in this environment.',
|
||||
"Please ensure you are using a supported browser or update your device's operating system to the latest version.",
|
||||
'If the issue persists, visit our <a href="https://github.com/toeverything/AFFiNE/issues">support page</a> for further assistance.',
|
||||
'</p>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
].join('');
|
||||
errorEl.setAttribute(
|
||||
'style',
|
||||
'position:absolute;top:0;left:0;height:100vh;width:100vw;display:flex;flex-direction:column;align-items:center;justify-content:center;background:white;z-index:999;'
|
||||
);
|
||||
document.body.append(errorEl);
|
||||
}
|
||||
|
||||
function registerGlobalErrorHandler() {
|
||||
function handleGlobalUnrecoverableError(
|
||||
e: ErrorEvent | PromiseRejectionEvent
|
||||
) {
|
||||
var error =
|
||||
'error' in e ? e.error : e.reason instanceof Error ? e.reason : null;
|
||||
console.error('unhandled unrecoverable error', error);
|
||||
|
||||
const shouldCache =
|
||||
// syntax error
|
||||
error && error instanceof SyntaxError;
|
||||
|
||||
if (!shouldCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.stopImmediatePropagation();
|
||||
showGlobalErrorPage();
|
||||
}
|
||||
if (typeof document !== 'undefined') {
|
||||
globalThis.addEventListener(
|
||||
'unhandledrejection',
|
||||
handleGlobalUnrecoverableError
|
||||
);
|
||||
globalThis.addEventListener('error', handleGlobalUnrecoverableError);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureBasicEnvironment() {
|
||||
var globals = ['Promise', 'Map', 'fetch', 'customElements'];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||
for (var i = 0; i < globals.length; i++) {
|
||||
if (!(globals[i] in globalThis)) {
|
||||
showGlobalErrorPage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerGlobalErrorHandler();
|
||||
ensureBasicEnvironment();
|
@ -5,11 +5,6 @@ function testPackageName(regexp: RegExp): (module: any) => boolean {
|
||||
|
||||
// https://hackernoon.com/the-100-correct-way-to-split-your-chunks-with-webpack-f8a9df5b7758
|
||||
export const productionCacheGroups = {
|
||||
errorHandler: {
|
||||
test: /global-error-handler/,
|
||||
priority: 1000,
|
||||
enforce: true,
|
||||
},
|
||||
asyncVendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name(module: any) {
|
||||
|
@ -400,11 +400,6 @@ export const createConfiguration: (
|
||||
maxInitialRequests: Infinity,
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
errorHandler: {
|
||||
test: /global-error-handler/,
|
||||
priority: 1000,
|
||||
enforce: true,
|
||||
},
|
||||
defaultVendors: {
|
||||
test: `[\\/]node_modules[\\/](?!.*vanilla-extract)`,
|
||||
priority: -10,
|
||||
|
73
tools/cli/src/webpack/error-handler.js
Normal file
73
tools/cli/src/webpack/error-handler.js
Normal file
@ -0,0 +1,73 @@
|
||||
(function () {
|
||||
var errorEl = null;
|
||||
function showGlobalErrorPage() {
|
||||
if (errorEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
errorEl = document.createElement('div');
|
||||
errorEl.innerHTML = [
|
||||
'<style>',
|
||||
'.gue {display:flex;flex-direction:column;align-items:center;justify-content:center;width:380px;}',
|
||||
'.gue img{width:380px;}',
|
||||
'.gue div{padding:16px 40px 0 40px;text-align:center;}',
|
||||
'.gue .p1{color:#141414;line-height:24px;font-weight:500;}',
|
||||
'.gue .p2{color:#7A7A7A;line-height:22px;}',
|
||||
'</style>',
|
||||
'<div class="gue">',
|
||||
'<img src="https://cdn.affine.pro/error.png" />',
|
||||
'<div>',
|
||||
'<p class="p1">Unsupported Environment</p>',
|
||||
'<p class="p2">',
|
||||
'It looks like AFFiNE cannot run in this environment.',
|
||||
"Please ensure you are using a supported browser or update your device's operating system to the latest version.",
|
||||
'If the issue persists, visit our <a href="https://github.com/toeverything/AFFiNE/issues">support page</a> for further assistance.',
|
||||
'</p>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
].join('');
|
||||
errorEl.setAttribute(
|
||||
'style',
|
||||
'position:absolute;top:0;left:0;height:100vh;width:100vw;display:flex;flex-direction:column;align-items:center;justify-content:center;background:white;z-index:999;'
|
||||
);
|
||||
document.body.append(errorEl);
|
||||
}
|
||||
|
||||
function registerGlobalErrorHandler() {
|
||||
function handler(e) {
|
||||
var error =
|
||||
'error' in e ? e.error : e.reason instanceof Error ? e.reason : null;
|
||||
console.error('unhandled unrecoverable error', error);
|
||||
|
||||
const shouldCache =
|
||||
// syntax error
|
||||
error && error instanceof SyntaxError;
|
||||
|
||||
if (!shouldCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.stopImmediatePropagation();
|
||||
showGlobalErrorPage();
|
||||
}
|
||||
if (typeof document !== 'undefined') {
|
||||
globalThis.addEventListener('unhandledrejection', handler);
|
||||
globalThis.addEventListener('error', handler);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureBasicEnvironment() {
|
||||
var globals = ['Promise', 'Map', 'fetch', 'customElements'];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||
for (var i = 0; i < globals.length; i++) {
|
||||
if (!(globals[i] in globalThis)) {
|
||||
showGlobalErrorPage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerGlobalErrorHandler();
|
||||
ensureBasicEnvironment();
|
||||
})();
|
@ -1,4 +1,5 @@
|
||||
import { execSync } from 'node:child_process';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join, resolve } from 'node:path';
|
||||
|
||||
import type { BuildFlags } from '@affine/cli/config';
|
||||
@ -52,6 +53,14 @@ export function createWebpackConfig(cwd: string, flags: BuildFlags) {
|
||||
? undefined
|
||||
: new URL(publicPath).origin;
|
||||
|
||||
const globalErrorHandler = [
|
||||
'js/global-error-handler.js',
|
||||
readFileSync(
|
||||
join(workspaceRoot, 'tools/cli/src/webpack/error-handler.js'),
|
||||
'utf-8'
|
||||
),
|
||||
];
|
||||
|
||||
const templateParams = {
|
||||
GIT_SHORT_SHA: gitShortHash(),
|
||||
DESCRIPTION,
|
||||
@ -86,7 +95,24 @@ export function createWebpackConfig(cwd: string, flags: BuildFlags) {
|
||||
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
|
||||
'assets-manifest-plugin',
|
||||
arg => {
|
||||
if (
|
||||
flags.distribution !== 'desktop' &&
|
||||
!compilation.getAsset(globalErrorHandler[0])
|
||||
) {
|
||||
compilation.emitAsset(
|
||||
globalErrorHandler[0],
|
||||
new webpack.sources.RawSource(globalErrorHandler[1])
|
||||
);
|
||||
arg.assets.js.unshift(
|
||||
arg.assets.publicPath + globalErrorHandler[0]
|
||||
);
|
||||
}
|
||||
|
||||
if (!compilation.getAsset('assets-manifest.json')) {
|
||||
compilation.emitAsset(
|
||||
globalErrorHandler[0],
|
||||
new webpack.sources.RawSource(globalErrorHandler[1])
|
||||
);
|
||||
compilation.emitAsset(
|
||||
`assets-manifest.json`,
|
||||
new webpack.sources.RawSource(
|
||||
|
Loading…
Reference in New Issue
Block a user