Merge pull request #69 from lbryio/high-level-error-handling
High-level error handling
This commit is contained in:
commit
f8c77a96cc
5 changed files with 110 additions and 1 deletions
BIN
dist/img/warning.png
vendored
Normal file
BIN
dist/img/warning.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
39
js/app.js
39
js/app.js
|
@ -1,4 +1,13 @@
|
||||||
var App = React.createClass({
|
var App = React.createClass({
|
||||||
|
_error_key_labels: {
|
||||||
|
connectionString: 'API connection string',
|
||||||
|
method: 'Method',
|
||||||
|
params: 'Parameters',
|
||||||
|
code: 'Error code',
|
||||||
|
message: 'Error message',
|
||||||
|
data: 'Error data',
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
// For now, routes are in format ?page or ?page=args
|
// For now, routes are in format ?page or ?page=args
|
||||||
var match, param, val, viewingPage,
|
var match, param, val, viewingPage,
|
||||||
|
@ -11,6 +20,7 @@ var App = React.createClass({
|
||||||
viewingPage: viewingPage,
|
viewingPage: viewingPage,
|
||||||
drawerOpen: drawerOpenRaw !== null ? JSON.parse(drawerOpenRaw) : true,
|
drawerOpen: drawerOpenRaw !== null ? JSON.parse(drawerOpenRaw) : true,
|
||||||
pageArgs: val,
|
pageArgs: val,
|
||||||
|
errorInfo: null,
|
||||||
modal: null,
|
modal: null,
|
||||||
startNotice: null,
|
startNotice: null,
|
||||||
updateUrl: null,
|
updateUrl: null,
|
||||||
|
@ -28,6 +38,10 @@ var App = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
|
document.addEventListener('unhandledError', (event) => {
|
||||||
|
this.alertError(event.detail);
|
||||||
|
});
|
||||||
|
|
||||||
lbry.checkNewVersionAvailable((isAvailable) => {
|
lbry.checkNewVersionAvailable((isAvailable) => {
|
||||||
if (!isAvailable || sessionStorage.getItem('upgradeSkipped')) {
|
if (!isAvailable || sessionStorage.getItem('upgradeSkipped')) {
|
||||||
return;
|
return;
|
||||||
|
@ -88,6 +102,19 @@ var App = React.createClass({
|
||||||
pageArgs: term
|
pageArgs: term
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
alertError: function(error) {
|
||||||
|
var errorInfoList = [];
|
||||||
|
for (let key of Object.keys(error)) {
|
||||||
|
let val = typeof error[key] == 'string' ? error[key] : JSON.stringify(error[key]);
|
||||||
|
let label = this._error_key_labels[key];
|
||||||
|
errorInfoList.push(<li key={key}><strong>{label}</strong>: <code>{val}</code></li>);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
modal: 'error',
|
||||||
|
errorInfo: <ul className="error-modal__error-list">{errorInfoList}</ul>,
|
||||||
|
});
|
||||||
|
},
|
||||||
getHeaderLinks: function()
|
getHeaderLinks: function()
|
||||||
{
|
{
|
||||||
switch(this.state.viewingPage)
|
switch(this.state.viewingPage)
|
||||||
|
@ -177,6 +204,18 @@ var App = React.createClass({
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal isOpen={this.state.modal == 'error'} type="custom" className="error-modal" overlayClassName="error-modal-overlay" >
|
||||||
|
<h3 className="modal__header">Error</h3>
|
||||||
|
|
||||||
|
<div className="error-modal__content">
|
||||||
|
<div><img className="error-modal__warning-symbol" src={lbry.imagePath('warning.png')} /></div>
|
||||||
|
<p>We're sorry that LBRY has encountered an error. This has been reported and we will investigate the problem.</p>
|
||||||
|
</div>
|
||||||
|
{this.state.errorInfo}
|
||||||
|
<div className="modal__buttons">
|
||||||
|
<Link button="alt" label="OK" className="modal__button" onClick={this.closeModal} />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
31
js/lbry.js
31
js/lbry.js
|
@ -30,12 +30,43 @@ lbry.jsonrpc_call = function (connectionString, method, params, callback, errorC
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
if (errorCallback) {
|
if (errorCallback) {
|
||||||
errorCallback(response.error);
|
errorCallback(response.error);
|
||||||
|
} else {
|
||||||
|
var errorEvent = new CustomEvent('unhandledError', {
|
||||||
|
detail: {
|
||||||
|
connectionString: connectionString,
|
||||||
|
method: method,
|
||||||
|
params: params,
|
||||||
|
code: response.error.code,
|
||||||
|
message: response.error.message,
|
||||||
|
data: response.error.data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.dispatchEvent(errorEvent)
|
||||||
}
|
}
|
||||||
} else if (callback) {
|
} else if (callback) {
|
||||||
callback(response.result);
|
callback(response.result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (connectFailedCallback) {
|
||||||
|
xhr.addEventListener('error', function (event) {
|
||||||
|
connectFailedCallback(event);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
xhr.addEventListener('error', function (event) {
|
||||||
|
var errorEvent = new CustomEvent('unhandledError', {
|
||||||
|
detail: {
|
||||||
|
connectionString: connectionString,
|
||||||
|
method: method,
|
||||||
|
params: params,
|
||||||
|
code: xhr.status,
|
||||||
|
message: 'Connection to API server failed'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.dispatchEvent(errorEvent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
xhr.open('POST', connectionString, true);
|
xhr.open('POST', connectionString, true);
|
||||||
xhr.send(JSON.stringify({
|
xhr.send(JSON.stringify({
|
||||||
'jsonrpc': '2.0',
|
'jsonrpc': '2.0',
|
||||||
|
|
|
@ -225,6 +225,10 @@ var MyFilesPage = React.createClass({
|
||||||
for (let fileInfo of filesInfo) {
|
for (let fileInfo of filesInfo) {
|
||||||
let name = fileInfo.lbry_uri;
|
let name = fileInfo.lbry_uri;
|
||||||
|
|
||||||
|
if (name === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
lbry.lighthouse.search(name, (results) => {
|
lbry.lighthouse.search(name, (results) => {
|
||||||
var result = results[0];
|
var result = results[0];
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,11 @@ label {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font: 0.8em Consolas, 'Lucida Console', 'Source Sans', monospace;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
p
|
p
|
||||||
{
|
{
|
||||||
margin-bottom: 0.8em;
|
margin-bottom: 0.8em;
|
||||||
|
@ -229,6 +234,7 @@ input[type="text"], input[type="search"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.modal-overlay {
|
.modal-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -254,10 +260,14 @@ input[type="text"], input[type="search"]
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
outline: none;
|
outline: none;
|
||||||
padding: 40px;
|
padding: 36px;
|
||||||
max-width: 250px;
|
max-width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal__header {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.modal__buttons {
|
.modal__buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -268,3 +278,28 @@ input[type="text"], input[type="search"]
|
||||||
.modal__button {
|
.modal__button {
|
||||||
margin: 0px 6px;
|
margin: 0px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-modal__error-list {
|
||||||
|
border: 1px solid #eee;
|
||||||
|
padding: 8px;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-modal-overlay {
|
||||||
|
background: rgba(#000, .88);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-modal {
|
||||||
|
max-width: none;
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-modal__content {
|
||||||
|
display: flex;
|
||||||
|
padding: 0px 8px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-modal__warning-symbol {
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue