mirror of
https://github.com/flarum/framework.git
synced 2025-03-28 18:25:14 +08:00
feat: Graceful frontend extension initialization failure (#3349)
This commit is contained in:
parent
4dfbaa3271
commit
ca7055f5d0
@ -33,6 +33,7 @@ import type Mithril from 'mithril';
|
|||||||
import type Component from './Component';
|
import type Component from './Component';
|
||||||
import type { ComponentAttrs } from './Component';
|
import type { ComponentAttrs } from './Component';
|
||||||
import Model, { SavedModelData } from './Model';
|
import Model, { SavedModelData } from './Model';
|
||||||
|
import fireApplicationError from './helpers/fireApplicationError';
|
||||||
|
|
||||||
export type FlarumScreens = 'phone' | 'tablet' | 'desktop' | 'desktop-hd';
|
export type FlarumScreens = 'phone' | 'tablet' | 'desktop' | 'desktop-hd';
|
||||||
|
|
||||||
@ -262,7 +263,25 @@ export default class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boot() {
|
public boot() {
|
||||||
this.initializers.toArray().forEach((initializer) => initializer(this));
|
const caughtInitializationErrors: CallableFunction[] = [];
|
||||||
|
|
||||||
|
this.initializers.toArray().forEach((initializer) => {
|
||||||
|
try {
|
||||||
|
initializer(this);
|
||||||
|
} catch (e) {
|
||||||
|
const extension = initializer.itemName.includes('/')
|
||||||
|
? initializer.itemName.replace(/(\/flarum-ext-)|(\/flarum-)/g, '-')
|
||||||
|
: initializer.itemName;
|
||||||
|
|
||||||
|
caughtInitializationErrors.push(() =>
|
||||||
|
fireApplicationError(
|
||||||
|
extractText(app.translator.trans('core.lib.error.extension_initialiation_failed_message', { extension })),
|
||||||
|
`${extension} failed to initialize`,
|
||||||
|
e
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.store.pushPayload({ data: this.data.resources });
|
this.store.pushPayload({ data: this.data.resources });
|
||||||
|
|
||||||
@ -273,6 +292,8 @@ export default class Application {
|
|||||||
this.mount();
|
this.mount();
|
||||||
|
|
||||||
this.initialRoute = window.location.href;
|
this.initialRoute = window.location.href;
|
||||||
|
|
||||||
|
caughtInitializationErrors.forEach((handler) => handler());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This entire system needs a do-over for v2
|
// TODO: This entire system needs a do-over for v2
|
||||||
|
18
framework/core/js/src/common/helpers/fireApplicationError.ts
Normal file
18
framework/core/js/src/common/helpers/fireApplicationError.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import app from '../app';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire a Flarum error which is shown in the JS console for everyone and in an alert for the admin.
|
||||||
|
*
|
||||||
|
* @param userTitle: a user friendly title of the error, should be localized.
|
||||||
|
* @param consoleTitle: an error title that goes in the console, doesn't have to be localized.
|
||||||
|
* @param error: the error.
|
||||||
|
*/
|
||||||
|
export default function fireApplicationError(userTitle: string, consoleTitle: string, error: any) {
|
||||||
|
console.group(`%c${consoleTitle}`, 'background-color: #d83e3e; color: #ffffff; font-weight: bold;');
|
||||||
|
console.error(error);
|
||||||
|
console.groupEnd();
|
||||||
|
|
||||||
|
if (app.session?.user?.isAdmin()) {
|
||||||
|
app.alerts.show({ type: 'error' }, `${userTitle}`);
|
||||||
|
}
|
||||||
|
}
|
@ -42,6 +42,10 @@ export default class User extends Model {
|
|||||||
return Model.hasMany<Group>('groups').call(this);
|
return Model.hasMany<Group>('groups').call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAdmin() {
|
||||||
|
return Model.attribute<boolean | undefined>('isAdmin').call(this);
|
||||||
|
}
|
||||||
|
|
||||||
joinTime() {
|
joinTime() {
|
||||||
return Model.attribute('joinTime', Model.transformDate).call(this);
|
return Model.attribute('joinTime', Model.transformDate).call(this);
|
||||||
}
|
}
|
||||||
|
@ -534,6 +534,7 @@ core:
|
|||||||
# These translations are displayed as error messages.
|
# These translations are displayed as error messages.
|
||||||
error:
|
error:
|
||||||
dependent_extensions_message: "Cannot disable {extension} until the following dependent extensions are disabled: {extensions}"
|
dependent_extensions_message: "Cannot disable {extension} until the following dependent extensions are disabled: {extensions}"
|
||||||
|
extension_initialiation_failed_message: "{extension} failed to initialize, check the browser console for further information."
|
||||||
generic_message: "Oops! Something went wrong. Please reload the page and try again."
|
generic_message: "Oops! Something went wrong. Please reload the page and try again."
|
||||||
missing_dependencies_message: "Cannot enable {extension} until the following dependencies are enabled: {extensions}"
|
missing_dependencies_message: "Cannot enable {extension} until the following dependencies are enabled: {extensions}"
|
||||||
not_found_message: The requested resource was not found.
|
not_found_message: The requested resource was not found.
|
||||||
|
@ -25,7 +25,8 @@ class CurrentUserSerializer extends UserSerializer
|
|||||||
'markedAllAsReadAt' => $this->formatDate($user->marked_all_as_read_at),
|
'markedAllAsReadAt' => $this->formatDate($user->marked_all_as_read_at),
|
||||||
'unreadNotificationCount' => (int) $user->getUnreadNotificationCount(),
|
'unreadNotificationCount' => (int) $user->getUnreadNotificationCount(),
|
||||||
'newNotificationCount' => (int) $user->getNewNotificationCount(),
|
'newNotificationCount' => (int) $user->getNewNotificationCount(),
|
||||||
'preferences' => (array) $user->preferences
|
'preferences' => (array) $user->preferences,
|
||||||
|
'isAdmin' => $user->isAdmin(),
|
||||||
];
|
];
|
||||||
|
|
||||||
return $attributes;
|
return $attributes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user