mirror of
https://github.com/ascribe/onion.git
synced 2024-12-23 01:39:36 +01:00
Merge pull request #1 from ascribe/AD-1177-display-404-on-pieces-and-editio
AD-1177 display 404 on pieces and editio
This commit is contained in:
commit
2b6b78310c
@ -7,7 +7,8 @@ import EditionFetcher from '../fetchers/edition_fetcher';
|
|||||||
class EditionActions {
|
class EditionActions {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.generateActions(
|
this.generateActions(
|
||||||
'updateEdition'
|
'updateEdition',
|
||||||
|
'editionFailed'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ class EditionActions {
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.logGlobal(err);
|
console.logGlobal(err);
|
||||||
|
this.actions.editionFailed(err.json);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@ class PieceActions {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.generateActions(
|
this.generateActions(
|
||||||
'updatePiece',
|
'updatePiece',
|
||||||
'updateProperty'
|
'updateProperty',
|
||||||
|
'pieceFailed'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ class PieceActions {
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.logGlobal(err);
|
console.logGlobal(err);
|
||||||
|
this.actions.pieceFailed(err.json);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { History } from 'react-router';
|
||||||
|
|
||||||
|
import ReactError from '../../mixins/react_error';
|
||||||
|
import { ResourceNotFoundError } from '../../models/errors';
|
||||||
|
|
||||||
import EditionActions from '../../actions/edition_actions';
|
import EditionActions from '../../actions/edition_actions';
|
||||||
import EditionStore from '../../stores/edition_store';
|
import EditionStore from '../../stores/edition_store';
|
||||||
@ -9,6 +13,7 @@ import Edition from './edition';
|
|||||||
|
|
||||||
import AscribeSpinner from '../ascribe_spinner';
|
import AscribeSpinner from '../ascribe_spinner';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
import { setDocumentTitle } from '../../utils/dom_utils';
|
import { setDocumentTitle } from '../../utils/dom_utils';
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +27,8 @@ let EditionContainer = React.createClass({
|
|||||||
params: React.PropTypes.object
|
params: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mixins: [History, ReactError],
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return EditionStore.getState();
|
return EditionStore.getState();
|
||||||
},
|
},
|
||||||
@ -29,11 +36,11 @@ let EditionContainer = React.createClass({
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
EditionStore.listen(this.onChange);
|
EditionStore.listen(this.onChange);
|
||||||
|
|
||||||
// Every time we enter the edition detail page, just reset the edition
|
// Every time we're entering the edition detail page,
|
||||||
// store as it will otherwise display wrong/old data once the user loads
|
// just reset the edition that is saved in the edition store
|
||||||
|
// as it will otherwise display wrong/old data once the user loads
|
||||||
// the edition detail a second time
|
// the edition detail a second time
|
||||||
EditionActions.updateEdition({});
|
EditionActions.updateEdition({});
|
||||||
|
|
||||||
this.loadEdition();
|
this.loadEdition();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -46,6 +53,14 @@ let EditionContainer = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { editionError } = this.state;
|
||||||
|
|
||||||
|
if(editionError && editionError.status === 404) {
|
||||||
|
this.throws(new ResourceNotFoundError(getLangText("Oops, the edition you're looking for doesn't exist.")));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.clearInterval(this.state.timerId);
|
window.clearInterval(this.state.timerId);
|
||||||
EditionStore.unlisten(this.onChange);
|
EditionStore.unlisten(this.onChange);
|
||||||
|
@ -4,6 +4,9 @@ import React from 'react';
|
|||||||
import { History } from 'react-router';
|
import { History } from 'react-router';
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
|
|
||||||
|
import ReactError from '../../mixins/react_error';
|
||||||
|
import { ResourceNotFoundError } from '../../models/errors';
|
||||||
|
|
||||||
import PieceActions from '../../actions/piece_actions';
|
import PieceActions from '../../actions/piece_actions';
|
||||||
import PieceStore from '../../stores/piece_store';
|
import PieceStore from '../../stores/piece_store';
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ let PieceContainer = React.createClass({
|
|||||||
params: React.PropTypes.object
|
params: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [History],
|
mixins: [History, ReactError],
|
||||||
|
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
@ -76,15 +79,22 @@ let PieceContainer = React.createClass({
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
UserStore.listen(this.onChange);
|
UserStore.listen(this.onChange);
|
||||||
PieceListStore.listen(this.onChange);
|
PieceListStore.listen(this.onChange);
|
||||||
UserActions.fetchCurrentUser();
|
|
||||||
PieceStore.listen(this.onChange);
|
PieceStore.listen(this.onChange);
|
||||||
|
|
||||||
// Every time we enter the piece detail page, just reset the piece
|
// Every time we enter the piece detail page, just reset the piece
|
||||||
// store as it will otherwise display wrong/old data once the user loads
|
// store as it will otherwise display wrong/old data once the user loads
|
||||||
// the piece detail a second time
|
// the piece detail a second time
|
||||||
PieceActions.updatePiece({});
|
PieceActions.updatePiece({});
|
||||||
|
|
||||||
this.loadPiece();
|
this.loadPiece();
|
||||||
|
UserActions.fetchCurrentUser();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { pieceError } = this.state;
|
||||||
|
|
||||||
|
if(pieceError && pieceError.status === 404) {
|
||||||
|
this.throws(new ResourceNotFoundError(getLangText("Oops, the piece you're looking for doesn't exist.")));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -6,6 +6,16 @@ import { getLangText } from '../utils/lang_utils';
|
|||||||
|
|
||||||
|
|
||||||
let ErrorNotFoundPage = React.createClass({
|
let ErrorNotFoundPage = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
message: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps() {
|
||||||
|
return {
|
||||||
|
message: getLangText("Oops, the page you are looking for doesn't exist.")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
@ -13,7 +23,7 @@ let ErrorNotFoundPage = React.createClass({
|
|||||||
<div className="error-wrapper">
|
<div className="error-wrapper">
|
||||||
<h1>404</h1>
|
<h1>404</h1>
|
||||||
<p>
|
<p>
|
||||||
{getLangText('Ups, the page you are looking for does not exist.')}
|
{this.props.message}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
16
js/mixins/react_error.js
Normal file
16
js/mixins/react_error.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import invariant from 'invariant';
|
||||||
|
|
||||||
|
const ReactError = {
|
||||||
|
throws(err) {
|
||||||
|
if(!err.handler) {
|
||||||
|
invariant(err.handler, 'Error thrown to ReactError did not have a `handler` function');
|
||||||
|
console.logGlobal('Error thrown to ReactError did not have a `handler` function');
|
||||||
|
} else {
|
||||||
|
err.handler(this, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReactError;
|
31
js/models/errors.js
Normal file
31
js/models/errors.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import ErrorNotFoundPage from '../components/error_not_found_page';
|
||||||
|
|
||||||
|
|
||||||
|
export class ResourceNotFoundError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = this.constructor.name;
|
||||||
|
this.message = message;
|
||||||
|
|
||||||
|
// `captureStackTrace` might not be available in IE:
|
||||||
|
// - http://stackoverflow.com/a/8460753/1263876
|
||||||
|
if(Error.captureStackTrace) {
|
||||||
|
Error.captureStackTrace(this, this.constructor.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler(component, err) {
|
||||||
|
const monkeyPatchedKey = `_${this.name}MonkeyPatched`;
|
||||||
|
|
||||||
|
if(!component.state[monkeyPatchedKey]) {
|
||||||
|
component.render = () => <ErrorNotFoundPage message={err.message} />;
|
||||||
|
component.setState({
|
||||||
|
[monkeyPatchedKey]: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,11 +7,17 @@ import EditionActions from '../actions/edition_actions';
|
|||||||
class EditionStore {
|
class EditionStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.edition = {};
|
this.edition = {};
|
||||||
|
this.editionError = null;
|
||||||
this.bindActions(EditionActions);
|
this.bindActions(EditionActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateEdition(edition) {
|
onUpdateEdition(edition) {
|
||||||
this.edition = edition;
|
this.edition = edition;
|
||||||
|
this.editionError = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditionFailed(error) {
|
||||||
|
this.editionError = error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,13 @@ import PieceActions from '../actions/piece_actions';
|
|||||||
class PieceStore {
|
class PieceStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.piece = {};
|
this.piece = {};
|
||||||
|
this.pieceError = null;
|
||||||
this.bindActions(PieceActions);
|
this.bindActions(PieceActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdatePiece(piece) {
|
onUpdatePiece(piece) {
|
||||||
this.piece = piece;
|
this.piece = piece;
|
||||||
|
this.pieceError = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdateProperty({key, value}) {
|
onUpdateProperty({key, value}) {
|
||||||
@ -21,6 +23,10 @@ class PieceStore {
|
|||||||
throw new Error('There is no piece defined in PieceStore or the piece object does not have the property you\'re looking for.');
|
throw new Error('There is no piece defined in PieceStore or the piece object does not have the property you\'re looking for.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onPieceFailed(err) {
|
||||||
|
this.pieceError = err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default alt.createStore(PieceStore, 'PieceStore');
|
export default alt.createStore(PieceStore, 'PieceStore');
|
||||||
|
@ -30,6 +30,15 @@ class Requests {
|
|||||||
reject(error);
|
reject(error);
|
||||||
} else if(body && body.detail) {
|
} else if(body && body.detail) {
|
||||||
reject(new Error(body.detail));
|
reject(new Error(body.detail));
|
||||||
|
} else if(!body.success) {
|
||||||
|
let error = new Error('Client Request Error');
|
||||||
|
error.json = {
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
type: response.type,
|
||||||
|
url: response.url
|
||||||
|
};
|
||||||
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
resolve(body);
|
resolve(body);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user