1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 09:23:13 +01:00

error handling first cut

This commit is contained in:
Tim Daubenschütz 2015-07-17 15:41:09 +02:00
parent 18a37057e5
commit af42bb8e67
25 changed files with 95 additions and 59 deletions

View File

@ -32,10 +32,10 @@
"react/wrap-multilines": 1 "react/wrap-multilines": 1
}, },
"globals": { "globals": {
"Raven": true,
"Intercom": true, "Intercom": true,
"fetch": true "fetch": true,
} "require": true
},
"plugins": [ "plugins": [
"react" "react"
], ],

View File

@ -51,9 +51,6 @@
ga('create', 'UA-60614729-2', 'auto'); ga('create', 'UA-60614729-2', 'auto');
</script> </script>
<!-- Logging for sentry -->
<script src="//cdn.ravenjs.com/1.1.19/raven.min.js"></script>
<!-- Intercom library --> <!-- Intercom library -->
<script> <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; (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;

View File

@ -17,7 +17,7 @@ class ApplicationActions {
this.actions.updateApplications(res.applications); this.actions.updateApplications(res.applications);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
refreshApplicationToken(applicationName) { refreshApplicationToken(applicationName) {
@ -26,7 +26,7 @@ class ApplicationActions {
this.actions.updateApplications(res.applications); this.actions.updateApplications(res.applications);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -17,7 +17,7 @@ class CoaActions {
this.actions.updateCoa(res.coa); this.actions.updateCoa(res.coa);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
create(edition) { create(edition) {
@ -26,7 +26,7 @@ class CoaActions {
this.actions.updateCoa(res.coa); this.actions.updateCoa(res.coa);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -17,7 +17,7 @@ class EditionActions {
this.actions.updateEdition(res.edition); this.actions.updateEdition(res.edition);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -45,7 +45,6 @@ class EditionListActions {
}) })
.catch((err) => { .catch((err) => {
reject(err); reject(err);
//console.log(err);
}); });
}); });

View File

@ -17,7 +17,7 @@ class LicenseActions {
this.actions.updateLicenses(res.licenses); this.actions.updateLicenses(res.licenses);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -32,7 +32,7 @@ class LoanContractActions {
} }
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.logGlobal(err);
this.actions.updateLoanContract({ this.actions.updateLoanContract({
contractKey: null, contractKey: null,
contractUrl: null, contractUrl: null,

View File

@ -18,7 +18,7 @@ class PieceActions {
this.actions.updatePiece(res.piece); this.actions.updatePiece(res.piece);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -53,7 +53,8 @@ class PieceListActions {
.fetchRequestActions() .fetchRequestActions()
.then((res) => { .then((res) => {
this.actions.updatePieceListRequestActions(res.piece_ids); this.actions.updatePieceListRequestActions(res.piece_ids);
}); })
.catch((err) => console.logGlobal(err));
} }
} }

View File

@ -18,7 +18,7 @@ class UserActions {
this.actions.updateCurrentUser(res.users[0]); this.actions.updateCurrentUser(res.users[0]);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
this.actions.updateCurrentUser({}); this.actions.updateCurrentUser({});
}); });
} }
@ -28,7 +28,7 @@ class UserActions {
this.actions.deleteCurrentUser(); this.actions.deleteCurrentUser();
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -17,7 +17,7 @@ class WalletSettingsActions {
this.actions.updateWalletSettings(res.wallet_settings); this.actions.updateWalletSettings(res.wallet_settings);
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -14,10 +14,14 @@ class WhitelabelActions {
fetchWhitelabel() { fetchWhitelabel() {
WhitelabelFetcher.fetch() WhitelabelFetcher.fetch()
.then((res) => { .then((res) => {
this.actions.updateWhitelabel(res.whitelabel); if(res && res.whitelabel) {
this.actions.updateWhitelabel(res.whitelabel);
} else {
this.actions.updateWhitelabel({});
}
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.logGlobal(err);
}); });
} }
} }

View File

@ -14,6 +14,9 @@ import getRoutes from './routes';
import requests from './utils/requests'; import requests from './utils/requests';
import { getSubdomainSettings } from './utils/constants_utils'; import { getSubdomainSettings } from './utils/constants_utils';
import { initLogging } from './utils/error_utils';
initLogging();
let headers = { let headers = {
'Accept': 'application/json', 'Accept': 'application/json',
@ -25,18 +28,10 @@ requests.defaults({
http: { http: {
headers: headers, headers: headers,
credentials: 'include' 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 { class AppGateway {
@ -57,7 +52,7 @@ class AppGateway {
} }
load(type) { load(type) {
Router.run(getRoutes(type), Router.HistoryLocation, (App, state) => { Router.run(getRoutes(type), Router.HistoryLocation, (App) => {
if (window.ga) { if (window.ga) {
window.ga('send', 'pageview'); window.ga('send', 'pageview');
} }
@ -71,3 +66,4 @@ class AppGateway {
let ag = new AppGateway(); let ag = new AppGateway();
ag.start(); ag.start();

View File

@ -117,7 +117,7 @@ let AccordionListItem = React.createClass({
getLicences() { getLicences() {
// convert this to acl_view_licences later // 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 ( return (
<span> <span>
<span>, </span> <span>, </span>

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
import React from 'react/addons'; import React from 'react/addons';
import Raven from 'raven-js';
import { getCookie } from '../../utils/fetch_api_utils'; import { getCookie } from '../../utils/fetch_api_utils';
import { getLangText } from '../../utils/lang_utils'; import { getLangText } from '../../utils/lang_utils';

View File

@ -2,6 +2,7 @@
import React from 'react'; import React from 'react';
import Router from 'react-router'; import Router from 'react-router';
import Raven from 'raven-js';
import UserActions from '../actions/user_actions'; import UserActions from '../actions/user_actions';
import UserStore from '../stores/user_store'; import UserStore from '../stores/user_store';
@ -69,14 +70,14 @@ let Header = React.createClass({
<span>ascribe </span> <span>ascribe </span>
<span className="glyph-ascribe-spool-chunked ascribe-color"></span> <span className="glyph-ascribe-spool-chunked ascribe-color"></span>
</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} />; logo = <img className="img-brand" src={this.state.whitelabel.logo} />;
} }
return logo; return logo;
}, },
getPoweredBy(){ getPoweredBy(){
if (this.state.whitelabel.logo) { if (this.state.whitelabel && this.state.whitelabel.logo) {
return ( return (
<li> <li>
<a className="pull-right" href="https://www.ascribe.io/" target="_blank"> <a className="pull-right" href="https://www.ascribe.io/" target="_blank">

View File

@ -142,7 +142,7 @@ let RegisterPiece = React.createClass( {
}, },
getSpecifyEditions() { 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 ( return (
<PropertyCollapsible <PropertyCollapsible
name="num_editions" name="num_editions"

View File

@ -14,6 +14,7 @@ let constants = {
'acl_loan', 'acl_share', 'acl_transfer', 'acl_unconsign', 'acl_unshare', 'acl_view', 'acl_loan', 'acl_share', 'acl_transfer', 'acl_unconsign', 'acl_unshare', 'acl_view',
'acl_withdraw_transfer'], 'acl_withdraw_transfer'],
'version': 0.1,
'csrftoken': 'csrftoken2', 'csrftoken': 'csrftoken2',
'subdomains': [ 'subdomains': [
{ {
@ -47,7 +48,10 @@ let constants = {
], ],
// in case of whitelabel customization, we store stuff here // in case of whitelabel customization, we store stuff here
'whitelabel': {} 'whitelabel': {},
'raven': {
'url': 'https://0955da3388c64ab29bd32c2a429f9ef4@app.getsentry.com/48351'
}
}; };
export default constants; export default constants;

39
js/utils/error_utils.js Normal file
View 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;
}

View File

@ -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. * Takes a list of object and merges their keys to one object.
* Uses mergeOptions for two objects. * Uses mergeOptions for two objects.
* @param {[type]} l [description] * @param {[type]} l [description]

View File

@ -1,11 +1,8 @@
'use strict'; 'use strict';
import { argsToQueryParams, getCookie } from '../utils/fetch_api_utils'; import { argsToQueryParams, getCookie } from '../utils/fetch_api_utils';
import AppConstants from '../constants/application_constants';
class UrlMapError extends Error {} import AppConstants from '../constants/application_constants';
class ServerError extends Error {}
class APIError extends Error {}
class Requests { class Requests {
@ -22,9 +19,9 @@ class Requests {
unpackResponse(response) { unpackResponse(response) {
if (response.status >= 500) { if (response.status >= 500) {
throw new ServerError(); console.logGlobal(new Error(response.status + ': Generic server error - ' + response.statusText));
} else if(response.status === 403) { } else if(response.status >= 400 && response.status < 500) {
Raven.captureException('csrftoken error'); console.logGlobal(new Error(response.status + ': Generic request error - ' + response.statusText));
} }
return response.text(); return response.text();
} }
@ -40,19 +37,12 @@ class Requests {
} }
} }
handleFatalError(err) { handleError(err) {
this.fatalErrorHandler(err); if (err instanceof TypeError) {
throw new ServerError(err); console.logGlobal('Server did not respond to the request. (Not even displayed a 500)');
} } else {
console.logGlobal(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) { getUrl(url) {
@ -65,7 +55,7 @@ class Requests {
if (!url.match(/^http/)) { if (!url.match(/^http/)) {
url = this.urlMap[url]; url = this.urlMap[url];
if (!url) { if (!url) {
throw new UrlMapError(`Cannot find a mapping for "${name}"`); throw new Error(`Cannot find a mapping for "${name}"`);
} }
} }
@ -107,11 +97,11 @@ class Requests {
merged.headers['X-CSRFToken'] = csrftoken; merged.headers['X-CSRFToken'] = csrftoken;
} }
merged.method = verb; merged.method = verb;
return fetch(url, merged) return fetch(url, merged)
.then(this.unpackResponse) .then(this.unpackResponse)
.then(this.customJSONparse) .then(this.customJSONparse)
.catch(this.handleFatalError.bind(this)) .catch(this.handleError);
.then(this.handleAPIError);
} }
get(url, params) { get(url, params) {
@ -143,7 +133,6 @@ class Requests {
defaults(options) { defaults(options) {
this.httpOptions = options.http || {}; this.httpOptions = options.http || {};
this.urlMap = options.urlMap || {}; this.urlMap = options.urlMap || {};
this.fatalErrorHandler = options.fatalErrorHandler || (() => {});
} }
} }

View File

@ -69,6 +69,7 @@
"jest-cli": "^0.4.0", "jest-cli": "^0.4.0",
"lodash": "^3.9.3", "lodash": "^3.9.3",
"object-assign": "^2.0.0", "object-assign": "^2.0.0",
"raven-js": "^1.1.19",
"react": "^0.13.2", "react": "^0.13.2",
"react-bootstrap": "~0.22.6", "react-bootstrap": "~0.22.6",
"react-datepicker": "~0.8.0", "react-datepicker": "~0.8.0",

View File

@ -21,7 +21,7 @@ $BASE_URL: '<%= BASE_URL %>';
@import 'ascribe_media_player'; @import 'ascribe_media_player';
@import 'ascribe_uploader'; @import 'ascribe_uploader';
@import 'ascribe_footer'; @import 'ascribe_footer';
@import 'ascribe-global-notification'; @import 'ascribe_global_notification';
@import 'ascribe_piece_register'; @import 'ascribe_piece_register';
@import 'offset_right'; @import 'offset_right';
@import 'ascribe_settings'; @import 'ascribe_settings';