mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 08:53:27 +03:00
feat(core): add global error handler (#8509)
This commit is contained in:
parent
4b77f6ed34
commit
9b31183bd1
@ -1,3 +1 @@
|
||||
import { setupBrowser } from '@affine/core/bootstrap';
|
||||
|
||||
await setupBrowser();
|
||||
import '@affine/core/bootstrap/browser';
|
||||
|
@ -1,6 +1,3 @@
|
||||
import '@affine/core/bootstrap/electron';
|
||||
import '@affine/component/theme';
|
||||
import './global.css';
|
||||
|
||||
import { setupElectron } from '@affine/core/bootstrap';
|
||||
|
||||
setupElectron();
|
||||
|
@ -1,6 +1,3 @@
|
||||
import '@affine/core/bootstrap/electron';
|
||||
import '@affine/component/theme';
|
||||
import '../global.css';
|
||||
|
||||
import { setupElectron } from '@affine/core/bootstrap';
|
||||
|
||||
setupElectron();
|
||||
|
@ -1,6 +1,3 @@
|
||||
import '@affine/core/bootstrap/browser';
|
||||
import '@affine/component/theme';
|
||||
import '@affine/core/mobile/styles/mobile.css';
|
||||
|
||||
import { setupBrowser } from '@affine/core/bootstrap';
|
||||
|
||||
await setupBrowser();
|
||||
|
@ -1,5 +1,2 @@
|
||||
import '@affine/core/bootstrap/browser';
|
||||
import '@affine/component/theme';
|
||||
|
||||
import { setupBrowser } from '@affine/core/bootstrap';
|
||||
|
||||
await setupBrowser();
|
||||
|
@ -1,4 +0,0 @@
|
||||
import '@affine/env/constant';
|
||||
import '../types/types.d.ts';
|
||||
|
||||
export { setupGlobal as setupEnvironment } from '@affine/env/global';
|
5
packages/frontend/core/src/bootstrap/browser.ts
Normal file
5
packages/frontend/core/src/bootstrap/browser.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// ORDER MATTERS
|
||||
import './global-error-handler';
|
||||
import './env';
|
||||
import './public-path';
|
||||
import './polyfill/browser';
|
4
packages/frontend/core/src/bootstrap/electron.ts
Normal file
4
packages/frontend/core/src/bootstrap/electron.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// ORDER MATTERS
|
||||
import './env';
|
||||
import './public-path';
|
||||
import './polyfill/electron';
|
6
packages/frontend/core/src/bootstrap/env.ts
Normal file
6
packages/frontend/core/src/bootstrap/env.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import '@affine/env/constant';
|
||||
import '../types/types.d.ts';
|
||||
|
||||
import { setupGlobal } from '@affine/env/global';
|
||||
|
||||
setupGlobal();
|
BIN
packages/frontend/core/src/bootstrap/error.png
Normal file
BIN
packages/frontend/core/src/bootstrap/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
81
packages/frontend/core/src/bootstrap/global-error-handler.ts
Normal file
81
packages/frontend/core/src/bootstrap/global-error-handler.ts
Normal file
@ -0,0 +1,81 @@
|
||||
/* 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();
|
@ -1,15 +0,0 @@
|
||||
import '../types/types.d.ts';
|
||||
|
||||
import { setupEnvironment } from './app';
|
||||
import { polyfillBrowser, polyfillElectron } from './polyfill';
|
||||
|
||||
export function setupElectron() {
|
||||
setupEnvironment();
|
||||
polyfillElectron();
|
||||
}
|
||||
|
||||
export async function setupBrowser() {
|
||||
setupEnvironment();
|
||||
__webpack_public_path__ = environment.publicPath;
|
||||
await polyfillBrowser();
|
||||
}
|
@ -3,13 +3,7 @@ import { polyfillPromise } from './promise-with-resolvers';
|
||||
import { polyfillEventLoop } from './request-idle-callback';
|
||||
import { polyfillResizeObserver } from './resize-observer';
|
||||
|
||||
export function polyfillElectron() {
|
||||
polyfillResizeObserver();
|
||||
}
|
||||
|
||||
export async function polyfillBrowser() {
|
||||
polyfillResizeObserver();
|
||||
polyfillEventLoop();
|
||||
await polyfillPromise();
|
||||
await polyfillDispose();
|
||||
}
|
||||
polyfillResizeObserver();
|
||||
polyfillEventLoop();
|
||||
await polyfillPromise();
|
||||
await polyfillDispose();
|
@ -0,0 +1,3 @@
|
||||
import { polyfillResizeObserver } from './resize-observer';
|
||||
|
||||
polyfillResizeObserver();
|
1
packages/frontend/core/src/bootstrap/public-path.ts
Normal file
1
packages/frontend/core/src/bootstrap/public-path.ts
Normal file
@ -0,0 +1 @@
|
||||
__webpack_public_path__ = environment.publicPath;
|
@ -5,6 +5,11 @@ 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) {
|
||||
|
@ -56,13 +56,7 @@ const OptimizeOptionOptions: (
|
||||
minChunks: 1,
|
||||
maxInitialRequests: Number.MAX_SAFE_INTEGER,
|
||||
maxAsyncRequests: Number.MAX_SAFE_INTEGER,
|
||||
cacheGroups:
|
||||
buildFlags.mode === 'production'
|
||||
? productionCacheGroups
|
||||
: {
|
||||
default: false,
|
||||
vendors: false,
|
||||
},
|
||||
cacheGroups: productionCacheGroups,
|
||||
},
|
||||
});
|
||||
|
||||
@ -404,6 +398,11 @@ 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,
|
||||
|
Loading…
Reference in New Issue
Block a user