mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-03 08:28:31 +00:00
Add an error catcher and error state for the chat scroller to hopefully allow chat to recover when React forgets how to DOM.
This commit is contained in:
parent
a0606a49a4
commit
8ba8e054a5
3 changed files with 81 additions and 2 deletions
|
@ -1,3 +1,8 @@
|
|||
<div class="list-header">4.0.0-beta1.6<span>@c643fcdd1cb8343964c3</span> <time datetime="2018-03-03">(2018-03-03)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Changed: Add an error handler to the chat scroller, along with alternative rendering when there is an error. This will hopefully stop chat breaking without automatically recovering.</li>
|
||||
</ul>
|
||||
|
||||
<div class="list-header">4.0.0-beta1.6<span>@c643fcdd1cb8343964c3</span> <time datetime="2018-03-01">(2018-03-01)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Changed: Add error handlers for the chat controller and chat container React components to, hopefully, stop chat from breaking entirely when React forgets how to DOM.</li>
|
||||
|
|
|
@ -336,7 +336,9 @@ export default class ChatHook extends Module {
|
|||
|
||||
this.ChatController.ready((cls, instances) => {
|
||||
const t = this,
|
||||
old_catch = cls.prototype.componentDidCatch;
|
||||
old_catch = cls.prototype.componentDidCatch,
|
||||
old_render = cls.prototype.render;
|
||||
|
||||
// Try catching errors. With any luck, maybe we can
|
||||
// recover from the error when we re-build?
|
||||
cls.prototype.componentDidCatch = function(err, info) {
|
||||
|
@ -351,6 +353,22 @@ export default class ChatHook extends Module {
|
|||
return old_catch.call(this, err, info);
|
||||
}
|
||||
|
||||
cls.prototype.render = function() {
|
||||
if ( this.state.ffz_errors > 0 ) {
|
||||
const React = t.web_munch.getModule('react'),
|
||||
e = React && React.createElement;
|
||||
|
||||
if ( ! e )
|
||||
return null;
|
||||
|
||||
return e('div', {
|
||||
className: 'tw-border-l tw-c-background-alt-2 tw-c-text tw-full-width tw-full-height tw-align-items-center tw-flex tw-flex-column tw-justify-content-center tw-relative'
|
||||
}, 'There was an error displaying chat.');
|
||||
|
||||
} else
|
||||
return old_render.call(this);
|
||||
}
|
||||
|
||||
for(const inst of instances) {
|
||||
const service = inst.chatService;
|
||||
if ( ! service._ffz_was_here )
|
||||
|
@ -375,6 +393,7 @@ export default class ChatHook extends Module {
|
|||
this.ChatContainer.ready((cls, instances) => {
|
||||
const t = this,
|
||||
old_catch = cls.prototype.componentDidCatch;
|
||||
|
||||
// Try catching errors. With any luck, maybe we can
|
||||
// recover from the error when we re-build?
|
||||
cls.prototype.componentDidCatch = function(err, info) {
|
||||
|
|
|
@ -15,6 +15,7 @@ export default class Scroller extends Module {
|
|||
this.inject('i18n');
|
||||
this.inject('chat');
|
||||
this.inject('site.fine');
|
||||
this.inject('site.web_munch');
|
||||
|
||||
this.ChatScroller = this.fine.define(
|
||||
'chat-scroller',
|
||||
|
@ -62,7 +63,61 @@ export default class Scroller extends Module {
|
|||
});
|
||||
|
||||
this.ChatScroller.ready((cls, instances) => {
|
||||
const t = this;
|
||||
const t = this,
|
||||
old_catch = cls.prototype.componentDidCatch,
|
||||
old_render = cls.prototype.render;
|
||||
|
||||
// Try catching errors. With any luck, maybe we can
|
||||
// recover from the error when we re-build?
|
||||
cls.prototype.componentDidCatch = function(err, info) {
|
||||
// Don't log infinitely if stuff gets super screwed up.
|
||||
const errs = this.state.ffz_errors || 0;
|
||||
if ( errs < 100 ) {
|
||||
this.setState({
|
||||
ffz_errors: errs + 1,
|
||||
ffz_total_errors: (this.state.ffz_total_errors||0) + 1
|
||||
});
|
||||
t.log.info('Error within Chat', err, info, errs);
|
||||
}
|
||||
|
||||
if ( old_catch )
|
||||
return old_catch.call(this, err, info);
|
||||
}
|
||||
|
||||
cls.prototype.ffzZeroErrors = function() {
|
||||
this.setState({ffz_errors: 0});
|
||||
}
|
||||
|
||||
cls.prototype.render = function() {
|
||||
if ( this.state.ffz_errors > 0 ) {
|
||||
let timer;
|
||||
const auto = this.state.ffz_total_errors < 10,
|
||||
React = t.web_munch.getModule('react'),
|
||||
e = React && React.createElement,
|
||||
handler = () => {
|
||||
clearTimeout(timer);
|
||||
this.ffzZeroErrors();
|
||||
}
|
||||
|
||||
if ( auto )
|
||||
timer = setTimeout(handler, 250);
|
||||
|
||||
if ( ! e )
|
||||
return null;
|
||||
|
||||
return e('div', {
|
||||
className: 'tw-border-l tw-c-background-alt-2 tw-c-text tw-full-width tw-full-height tw-align-items-center tw-flex tw-flex-column tw-justify-content-center tw-relative'
|
||||
}, [
|
||||
e('div', {className: 'tw-mg-b-1'}, 'There was an error displaying chat.'),
|
||||
! auto && e('button', {
|
||||
className: 'tw-button',
|
||||
onClick: handler
|
||||
}, e('span', {className: 'tw-button__text'}, 'Try Again'))
|
||||
]);
|
||||
|
||||
} else
|
||||
return old_render.call(this);
|
||||
}
|
||||
|
||||
cls.prototype.ffzShouldBeFrozen = function(since) {
|
||||
if ( since === undefined )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue