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

feat: Graceful frontend extension initialization failure #3349

Merged
merged 5 commits into from
Apr 3, 2022

Conversation

SychO9
Copy link
Member

@SychO9 SychO9 commented Mar 16, 2022

Part of flarum/issue-archive#85

Changes proposed in this pull request:
Instead of allowing the application's frontend to crash, we can catch the frontend errors when initializing extensions and gracefully fail to minimize the impact and improve user experience.

Reviewers should focus on:
The approach, error message formulation, general code quality.

Screenshot

Before After
Screenshot from 2022-03-16 14-17-21 Screenshot from 2022-03-16 14-12-25

Necessity

  • Has the problem that is being solved here been clearly explained?
  • If applicable, have various options for solving this problem been considered?
  • For core PRs, does this need to be in core, or could it be in an extension?
  • Are we willing to maintain this for years / potentially forever?

Confirmed

  • Frontend changes: tested on a local Flarum installation.
  • Backend changes: tests are green (run composer test).
  • Core developer confirmed locally this works as intended.
  • Tests have been added, or are not appropriate here.

@SychO9 SychO9 force-pushed the sm/graceful-frontend-js-failure branch from a28d7a2 to 993d6d3 Compare March 23, 2022 17:34
@SychO9 SychO9 marked this pull request as ready for review March 23, 2022 17:42
this.initializers.toArray().forEach((initializer) => {
try {
initializer(this);
} catch (e) {
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Shouldn't we rethrow e so the original error is accessible?

Copy link
Member Author

Choose a reason for hiding this comment

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

The error is still accessible since we display it with console.error in the introduced helper. (see screenshot above)
If we throw the execution halts and the app will display the nojs content:

try {
flarum.core.app.load(@json($payload));
flarum.core.app.bootExtensions(flarum.extensions);
flarum.core.app.boot();
} catch (e) {
var error = document.getElementById('flarum-loading-error');
error.innerHTML += document.getElementById('flarum-content').textContent;
error.style.display = 'block';
throw e;
}

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Makes sense!


caughtInitializationErrors.push(() => fireApplicationError({
userTitle: extractText(app.translator.trans('core.lib.error.extension_initialiation_failed_message', { extension })),
consoleTitle: `${extension} failed to initialize`,
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Why keep this untranslated?

Copy link
Member Author

Choose a reason for hiding this comment

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

Didn't think it would need translation since it's a console message along with English error messages. These will most of the time be copy-pasted to extension authors.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with that there's no reason to translate this.

* }
* @param errors
*/
export default function fireApplicationError(options: { userTitle: string, consoleTitle: string }, ...errors: any) {
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

Ooo I like this!

@dsevillamartin
Copy link
Member

Seems to work fine.


I do wonder if there's something we could do to make it able to be monkey patched by e.g. Sentry in order to report these errors. Only way these errors would be caught now would be with console logging enabled.

Think that's an issue more in general with exporting functions, however. I believe we've had some issues relating to that in the past? Unsure. Just some thoughts.

@SychO9
Copy link
Member Author

SychO9 commented Apr 3, 2022

Good point for a good use case. But yeah if it were to be done, monkey patching the function itself would be the best approach, which yeah isn't possible right now, but will be once the export registry is tackled, which is on the 1.x roadmap.

@SychO9 SychO9 merged commit ca7055f into main Apr 3, 2022
@SychO9 SychO9 deleted the sm/graceful-frontend-js-failure branch April 3, 2022 21:17
@SychO9 SychO9 added this to the 1.3 milestone Apr 3, 2022
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.

3 participants