mirror of
https://github.com/ascribe/onion.git
synced 2024-11-15 01:25:17 +01:00
Merged in AD-586-implement-logging-for-whole-app (pull request #12)
Ad 586 implement logging for whole app
This commit is contained in:
commit
658a4b3372
@ -32,10 +32,10 @@
|
||||
"react/wrap-multilines": 1
|
||||
},
|
||||
"globals": {
|
||||
"Raven": true,
|
||||
"Intercom": true,
|
||||
"fetch": true
|
||||
}
|
||||
"fetch": true,
|
||||
"require": true
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
|
@ -51,9 +51,6 @@
|
||||
ga('create', 'UA-60614729-2', 'auto');
|
||||
</script>
|
||||
|
||||
<!-- Logging for sentry -->
|
||||
<script src="//cdn.ravenjs.com/1.1.19/raven.min.js"></script>
|
||||
|
||||
<!-- Intercom library -->
|
||||
<script>
|
||||
(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;
|
||||
|
@ -17,7 +17,7 @@ class ApplicationActions {
|
||||
this.actions.updateApplications(res.applications);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
refreshApplicationToken(applicationName) {
|
||||
@ -26,7 +26,7 @@ class ApplicationActions {
|
||||
this.actions.updateApplications(res.applications);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class CoaActions {
|
||||
this.actions.updateCoa(res.coa);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
create(edition) {
|
||||
@ -26,7 +26,7 @@ class CoaActions {
|
||||
this.actions.updateCoa(res.coa);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class EditionActions {
|
||||
this.actions.updateEdition(res.edition);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ class EditionListActions {
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
//console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@ class LicenseActions {
|
||||
this.actions.updateLicenses(res.licenses);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class LoanContractActions {
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
console.logGlobal(err);
|
||||
this.actions.updateLoanContract({
|
||||
contractKey: null,
|
||||
contractUrl: null,
|
||||
|
@ -18,7 +18,7 @@ class PieceActions {
|
||||
this.actions.updatePiece(res.piece);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ class PieceListActions {
|
||||
.fetchRequestActions()
|
||||
.then((res) => {
|
||||
this.actions.updatePieceListRequestActions(res.piece_ids);
|
||||
});
|
||||
})
|
||||
.catch((err) => console.logGlobal(err));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ class UserActions {
|
||||
this.actions.updateCurrentUser(res.users[0]);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
this.actions.updateCurrentUser({});
|
||||
});
|
||||
}
|
||||
@ -28,7 +28,7 @@ class UserActions {
|
||||
this.actions.deleteCurrentUser();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class WalletSettingsActions {
|
||||
this.actions.updateWalletSettings(res.wallet_settings);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,14 @@ class WhitelabelActions {
|
||||
fetchWhitelabel() {
|
||||
WhitelabelFetcher.fetch()
|
||||
.then((res) => {
|
||||
this.actions.updateWhitelabel(res.whitelabel);
|
||||
if(res && res.whitelabel) {
|
||||
this.actions.updateWhitelabel(res.whitelabel);
|
||||
} else {
|
||||
this.actions.updateWhitelabel({});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
15
js/app.js
15
js/app.js
@ -14,6 +14,9 @@ import getRoutes from './routes';
|
||||
import requests from './utils/requests';
|
||||
|
||||
import { getSubdomainSettings } from './utils/constants_utils';
|
||||
import { initLogging } from './utils/error_utils';
|
||||
|
||||
initLogging();
|
||||
|
||||
let headers = {
|
||||
'Accept': 'application/json',
|
||||
@ -25,18 +28,10 @@ requests.defaults({
|
||||
http: {
|
||||
headers: headers,
|
||||
credentials: 'include'
|
||||
},
|
||||
fatalErrorHandler: (err) => {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
|
||||
Raven.config('https://0955da3388c64ab29bd32c2a429f9ef4@app.getsentry.com/48351', {
|
||||
// pass along the version of your application
|
||||
release: '1.0.0'
|
||||
}).install();
|
||||
|
||||
window.onerror = Raven.process;
|
||||
|
||||
class AppGateway {
|
||||
|
||||
@ -52,12 +47,13 @@ class AppGateway {
|
||||
} catch(err) {
|
||||
// if there are no matching subdomains, we're routing
|
||||
// to the default frontend
|
||||
console.logGlobal(err);
|
||||
this.load('default');
|
||||
}
|
||||
}
|
||||
|
||||
load(type) {
|
||||
Router.run(getRoutes(type), Router.HistoryLocation, (App, state) => {
|
||||
Router.run(getRoutes(type), Router.HistoryLocation, (App) => {
|
||||
if (window.ga) {
|
||||
window.ga('send', 'pageview');
|
||||
}
|
||||
@ -71,3 +67,4 @@ class AppGateway {
|
||||
|
||||
let ag = new AppGateway();
|
||||
ag.start();
|
||||
|
||||
|
@ -117,7 +117,7 @@ let AccordionListItem = React.createClass({
|
||||
|
||||
getLicences() {
|
||||
// convert this to acl_view_licences later
|
||||
if (this.state.whitelabel.name === 'Creative Commons France') {
|
||||
if (this.state.whitelabel && this.state.whitelabel.name === 'Creative Commons France') {
|
||||
return (
|
||||
<span>
|
||||
<span>, </span>
|
||||
|
@ -80,6 +80,7 @@ let Form = React.createClass({
|
||||
this.setState({edited: false, submitted: false});
|
||||
},
|
||||
handleError(err){
|
||||
console.log(err);
|
||||
if (err.json) {
|
||||
for (var input in err.json.errors){
|
||||
if (this.refs && this.refs[input] && this.refs[input].state) {
|
||||
@ -90,7 +91,7 @@ let Form = React.createClass({
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error(err);
|
||||
console.logGlobal(err);
|
||||
this.setState({errors: [getLangText('Something went wrong, please try again later')]});
|
||||
}
|
||||
this.setState({submitted: false});
|
||||
|
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react/addons';
|
||||
import Raven from 'raven-js';
|
||||
|
||||
import { getCookie } from '../../utils/fetch_api_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
@ -270,7 +271,7 @@ var ReactS3FineUploader = React.createClass({
|
||||
})
|
||||
.catch((err) => {
|
||||
defer.failure(err);
|
||||
console.error(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
return defer;
|
||||
},
|
||||
|
@ -53,6 +53,11 @@ let GlobalNotification = React.createClass({
|
||||
onChange(state) {
|
||||
let notification = this.extractFirstElem(state.notificationQue);
|
||||
|
||||
// error handling for notifications
|
||||
if(notification.message && notification.type === 'danger') {
|
||||
console.logGlobal(new Error(notification.message.message));
|
||||
}
|
||||
|
||||
if(notification.show) {
|
||||
this.setState(notification);
|
||||
} else {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
import Raven from 'raven-js';
|
||||
|
||||
import UserActions from '../actions/user_actions';
|
||||
import UserStore from '../stores/user_store';
|
||||
@ -59,14 +60,14 @@ let Header = React.createClass({
|
||||
<span>ascribe </span>
|
||||
<span className="glyph-ascribe-spool-chunked ascribe-color"></span>
|
||||
</span>);
|
||||
if (this.state.whitelabel.logo){
|
||||
if (this.state.whitelabel && this.state.whitelabel.logo){
|
||||
logo = <img className="img-brand" src={this.state.whitelabel.logo} />;
|
||||
}
|
||||
return logo;
|
||||
},
|
||||
|
||||
getPoweredBy(){
|
||||
if (this.state.whitelabel.logo) {
|
||||
if (this.state.whitelabel && this.state.whitelabel.logo) {
|
||||
return (
|
||||
<li>
|
||||
<a className="pull-right" href="https://www.ascribe.io/" target="_blank">
|
||||
|
@ -142,7 +142,7 @@ let RegisterPiece = React.createClass( {
|
||||
},
|
||||
|
||||
getSpecifyEditions() {
|
||||
if(this.state.whitelabel.acl_editions || Object.keys(this.state.whitelabel).length === 0) {
|
||||
if(this.state.whitelabel && this.state.whitelabel.acl_editions || Object.keys(this.state.whitelabel).length === 0) {
|
||||
return (
|
||||
<PropertyCollapsible
|
||||
name="num_editions"
|
||||
|
@ -14,6 +14,7 @@ let constants = {
|
||||
'acl_loan', 'acl_share', 'acl_transfer', 'acl_unconsign', 'acl_unshare', 'acl_view',
|
||||
'acl_withdraw_transfer'],
|
||||
|
||||
'version': 0.1,
|
||||
'csrftoken': 'csrftoken2',
|
||||
'subdomains': [
|
||||
{
|
||||
@ -47,7 +48,10 @@ let constants = {
|
||||
],
|
||||
|
||||
// in case of whitelabel customization, we store stuff here
|
||||
'whitelabel': {}
|
||||
'whitelabel': {},
|
||||
'raven': {
|
||||
'url': 'https://0955da3388c64ab29bd32c2a429f9ef4@app.getsentry.com/48351'
|
||||
}
|
||||
};
|
||||
|
||||
export default constants;
|
||||
|
@ -11,9 +11,9 @@ let EditionListFetcher = {
|
||||
*/
|
||||
fetch(pieceId, page, pageSize, orderBy, orderAsc) {
|
||||
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||
return requests.get('editions_list', {
|
||||
return requests.get('editions_list', {
|
||||
'piece_id': pieceId,
|
||||
page,
|
||||
page,
|
||||
pageSize,
|
||||
ordering
|
||||
});
|
||||
|
@ -87,7 +87,7 @@ class EditionListStore {
|
||||
this.editionList[pieceId].pageSize = prevEditionListPageSize;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
39
js/utils/error_utils.js
Normal file
39
js/utils/error_utils.js
Normal file
@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
import Raven from 'raven-js';
|
||||
|
||||
import AppConstants from '../constants/application_constants';
|
||||
|
||||
|
||||
/**
|
||||
* Logs an error in to the console but also sends it to
|
||||
* Sentry.
|
||||
* Optionally, a comment can be defined.
|
||||
* @param {Error} error a Javascript error
|
||||
* @param {boolean} ignoreSentry Defines whether or not the error should be submitted to Sentry
|
||||
* @param {string} comment Will also be submitted to Sentry, but will not be logged
|
||||
*/
|
||||
function logGlobal(error, ignoreSentry, comment) {
|
||||
|
||||
console.error(error);
|
||||
|
||||
if(!ignoreSentry) {
|
||||
if(comment) {
|
||||
Raven.captureException(error, {extra: { comment }});
|
||||
} else {
|
||||
Raven.captureException(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function initLogging() {
|
||||
// Initialize Raven for logging on Sentry
|
||||
Raven.config(AppConstants.raven.url, {
|
||||
release: AppConstants.version
|
||||
}).install();
|
||||
|
||||
window.onerror = Raven.process;
|
||||
|
||||
console.logGlobal = logGlobal;
|
||||
}
|
@ -114,6 +114,10 @@ export function mergeOptions(...l) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a number of objects even if there're having duplicates.
|
||||
*
|
||||
* DOES NOT RETURN AN ERROR!
|
||||
*
|
||||
* Takes a list of object and merges their keys to one object.
|
||||
* Uses mergeOptions for two objects.
|
||||
* @param {[type]} l [description]
|
||||
|
@ -1,11 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
import { argsToQueryParams, getCookie } from '../utils/fetch_api_utils';
|
||||
import AppConstants from '../constants/application_constants';
|
||||
|
||||
class UrlMapError extends Error {}
|
||||
class ServerError extends Error {}
|
||||
class APIError extends Error {}
|
||||
import AppConstants from '../constants/application_constants';
|
||||
|
||||
|
||||
class Requests {
|
||||
@ -22,39 +19,47 @@ class Requests {
|
||||
|
||||
unpackResponse(response) {
|
||||
if (response.status >= 500) {
|
||||
throw new ServerError();
|
||||
} else if(response.status === 403) {
|
||||
Raven.captureException('csrftoken error');
|
||||
throw new Error(response.status + ' - ' + response.statusText + ' - on URL:' + response.url);
|
||||
}
|
||||
return response.text();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
response.text()
|
||||
.then((responseText) => {
|
||||
// If the responses' body does not contain any data,
|
||||
// fetch will resolve responseText to the string 'None'.
|
||||
// If this is the case, we can not try to parse it as JSON.
|
||||
if(responseText !== 'None') {
|
||||
let body = JSON.parse(responseText);
|
||||
|
||||
if(body && body.errors) {
|
||||
let error = new Error('Form Error');
|
||||
error.json = body;
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(body);
|
||||
}
|
||||
|
||||
} else {
|
||||
if(response.status >= 400) {
|
||||
reject(new Error(response.status + ' - ' + response.statusText + ' - on URL:' + response.url));
|
||||
} else {
|
||||
resolve({});
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
customJSONparse(responseText) {
|
||||
// If the responses' body does not contain any data,
|
||||
// fetch will resolve responseText to the string 'None'.
|
||||
// If this is the case, we can not try to parse it as JSON.
|
||||
if(responseText !== 'None') {
|
||||
return JSON.parse(responseText);
|
||||
handleError(err) {
|
||||
if (err instanceof TypeError) {
|
||||
throw new Error('Server did not respond to the request. (Not even displayed a 500)');
|
||||
} else {
|
||||
return {};
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
handleFatalError(err) {
|
||||
this.fatalErrorHandler(err);
|
||||
throw new ServerError(err);
|
||||
}
|
||||
|
||||
handleAPIError(json) {
|
||||
if (json.success === false) {
|
||||
let error = new APIError();
|
||||
error.json = json;
|
||||
//console.error(new Error('The \'success\' property is missing in the server\'s response.'));
|
||||
throw error;
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
getUrl(url) {
|
||||
// Handle case, that the url string is not defined at all
|
||||
if (!url) {
|
||||
@ -65,7 +70,7 @@ class Requests {
|
||||
if (!url.match(/^http/)) {
|
||||
url = this.urlMap[url];
|
||||
if (!url) {
|
||||
throw new UrlMapError(`Cannot find a mapping for "${name}"`);
|
||||
throw new Error(`Cannot find a mapping for "${name}"`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,11 +112,10 @@ class Requests {
|
||||
merged.headers['X-CSRFToken'] = csrftoken;
|
||||
}
|
||||
merged.method = verb;
|
||||
|
||||
return fetch(url, merged)
|
||||
.then(this.unpackResponse)
|
||||
.then(this.customJSONparse)
|
||||
.catch(this.handleFatalError.bind(this))
|
||||
.then(this.handleAPIError);
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
get(url, params) {
|
||||
@ -143,7 +147,6 @@ class Requests {
|
||||
defaults(options) {
|
||||
this.httpOptions = options.http || {};
|
||||
this.urlMap = options.urlMap || {};
|
||||
this.fatalErrorHandler = options.fatalErrorHandler || (() => {});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@
|
||||
"jest-cli": "^0.4.0",
|
||||
"lodash": "^3.9.3",
|
||||
"object-assign": "^2.0.0",
|
||||
"raven-js": "^1.1.19",
|
||||
"react": "^0.13.2",
|
||||
"react-bootstrap": "~0.22.6",
|
||||
"react-datepicker": "~0.8.0",
|
||||
|
@ -21,7 +21,7 @@ $BASE_URL: '<%= BASE_URL %>';
|
||||
@import 'ascribe_media_player';
|
||||
@import 'ascribe_uploader';
|
||||
@import 'ascribe_footer';
|
||||
@import 'ascribe-global-notification';
|
||||
@import 'ascribe_global_notification';
|
||||
@import 'ascribe_piece_register';
|
||||
@import 'offset_right';
|
||||
@import 'ascribe_settings';
|
||||
|
Loading…
Reference in New Issue
Block a user