mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-07-21 19:24:15 +00:00
chore(Merge): branch 'develop' into origin-paglias-bs3
Conflicts: views/options/social/tavern.jade
This commit is contained in:
commit
ce8351d622
8 changed files with 56 additions and 84 deletions
|
|
@ -40,7 +40,6 @@
|
|||
"pretty-data": "git://github.com/vkiryukhin/pretty-data#master",
|
||||
"js2xmlparser": "~0.1.2",
|
||||
"mongoose": "~3.8.1",
|
||||
"domain-middleware": "~0.1.0",
|
||||
"swagger-node-express": "git://github.com/lefnire/swagger-node-express#habitrpg",
|
||||
"passport": "~0.1.18",
|
||||
"passport-facebook": "~1.0.2",
|
||||
|
|
@ -48,7 +47,8 @@
|
|||
"connect-ratelimit": "0.0.6",
|
||||
"winston": "~0.7.2",
|
||||
"winston-mail": "~0.2.7",
|
||||
"winston-newrelic": "~0.1.4"
|
||||
"winston-newrelic": "~0.1.4",
|
||||
"domain-middleware": "~0.1.0"
|
||||
},
|
||||
"private": true,
|
||||
"subdomain": "habitrpg",
|
||||
|
|
|
|||
|
|
@ -200,24 +200,40 @@ window.habitrpg = angular.module('habitrpg',
|
|||
}
|
||||
|
||||
// Handle errors
|
||||
var interceptor = ['$rootScope', '$q', function ($rootScope, $q) {
|
||||
$httpProvider.responseInterceptors.push(['$rootScope', '$q', function ($rootScope, $q) {
|
||||
function success(response) {
|
||||
return response;
|
||||
}
|
||||
function error(response) {
|
||||
//var status = response.status;
|
||||
response.data = (response.data.err) ? response.data.err : response.data;
|
||||
if (response.status == 0) response.data = window.env.t('serverUnreach');
|
||||
if (response.status == 500) response.data += window.env.t('seeConsole');
|
||||
debugger;
|
||||
// Offline
|
||||
if (response.status == 0 ||
|
||||
// don't know why we're getting 404 here, should be 0
|
||||
(response.status == 404 && _.isEmpty(response.data))) {
|
||||
$rootScope.$broadcast('responseText', window.env.t('serverUnreach'));
|
||||
|
||||
var error = response.status == 0 ? response.data : (window.env.t('error') + ' ' + response.status + ': ' + response.data);
|
||||
$rootScope.$broadcast('responseError', error);
|
||||
console.log(arguments);
|
||||
return $q.reject(response);
|
||||
// Needs refresh
|
||||
} else if (response.needRefresh) {
|
||||
$rootScope.$broadcast('responseError', "The site has been updated and the page needs to refresh. The last action has not been recorded, please refresh and try again.");
|
||||
|
||||
// 400 range?
|
||||
} else if (response < 500) {
|
||||
$rootScope.$broadcast('responseText', response.data.err || response.data);
|
||||
|
||||
// Error
|
||||
} else {
|
||||
var error = '<strong>Please reload</strong>, ' +
|
||||
'"'+window.env.t('error')+' '+(response.data.err || response.data || 'something went wrong')+'"' +
|
||||
window.env.t('seeConsole');
|
||||
$rootScope.$broadcast('responseError', error);
|
||||
console.error(response);
|
||||
}
|
||||
|
||||
//return $q.reject(response); // this completely halts the chain, meaning we can't queue offline actions
|
||||
return response;
|
||||
}
|
||||
return function (promise) {
|
||||
return promise.then(success, error);
|
||||
}
|
||||
}];
|
||||
$httpProvider.responseInterceptors.push(interceptor);
|
||||
}]);
|
||||
}])
|
||||
|
|
|
|||
|
|
@ -137,5 +137,8 @@ habitrpg.controller('NotificationCtrl',
|
|||
$rootScope.$on('responseError', function(ev, error){
|
||||
Notification.error(error);
|
||||
});
|
||||
$rootScope.$on('responseText', function(ev, error){
|
||||
Notification.text(error);
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ angular.module("notificationServices", [])
|
|||
top_offset: 20,
|
||||
align: 'right', //('left', 'right', or 'center')
|
||||
width: 250, //(integer, or 'auto')
|
||||
delay: 7000,
|
||||
delay: (type=='error') ? 0 : 7000,
|
||||
allow_dismiss: true,
|
||||
stackup_spacing: 10 // spacing between consecutive stacecked growls.
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ var limiter = require('connect-ratelimit');
|
|||
var logging = require('./logging');
|
||||
|
||||
module.exports.apiThrottle = function(app) {
|
||||
if (nconf.get('NODE_ENV') !== 'production') return;
|
||||
app.use(limiter({
|
||||
end:false,
|
||||
catagories:{
|
||||
|
|
@ -23,6 +24,23 @@ module.exports.apiThrottle = function(app) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports.errorHandler = function(err, req, res, next) {
|
||||
//res.locals.domain.emit('error', err);
|
||||
// when we hit an error, send it to admin as an email. If no ADMIN_EMAIL is present, just send it to yourself (SMTP_USER)
|
||||
var stack = (err.stack ? err.stack : err.message ? err.message : err) +
|
||||
"\n ----------------------------\n" +
|
||||
"\n\noriginalUrl: " + req.originalUrl +
|
||||
"\n\nauth: " + req.headers['x-api-user'] + ' | ' + req.headers['x-api-key'] +
|
||||
"\n\nheaders: " + JSON.stringify(req.headers) +
|
||||
"\n\nbody: " + JSON.stringify(req.body) +
|
||||
(res.locals.ops ? "\n\ncompleted ops: " + JSON.stringify(res.locals.ops) : "");
|
||||
logging.error(stack);
|
||||
var message = err.message ? err.message : err;
|
||||
message = (message.length < 200) ? message : message.substring(0,100) + message.substring(message.length-100,message.length);
|
||||
res.json(500,{err:message}); //res.end(err.message);
|
||||
}
|
||||
|
||||
|
||||
module.exports.forceSSL = function(req, res, next){
|
||||
var baseUrl = nconf.get("BASE_URL");
|
||||
// Note x-forwarded-proto is used by Heroku & nginx, you'll have to do something different if you're not using those
|
||||
|
|
@ -194,7 +212,7 @@ module.exports.locals = function(req, res, next) {
|
|||
if(err) return res.json(500, {err: err});
|
||||
|
||||
var isStaticPage = req.url.split('/')[1] === 'static'; // If url contains '/static/'
|
||||
console.log(isStaticPage)
|
||||
//console.log(isStaticPage)
|
||||
|
||||
// Load moment.js language file only when not on static pages
|
||||
language.momentLang = ((!isStaticPage && momentLangs[language.code])|| undefined);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
// Only do the minimal amount of work before forking just in case of a dyno restart
|
||||
var cluster = require("cluster");
|
||||
var _ = require('lodash');
|
||||
var nconf = require('nconf');
|
||||
var utils = require('./utils');
|
||||
|
|
@ -8,23 +7,10 @@ var logging = require('./logging');
|
|||
var isProd = nconf.get('NODE_ENV') === 'production';
|
||||
var isDev = nconf.get('NODE_ENV') === 'development';
|
||||
|
||||
if (cluster.isMaster && (isDev || isProd)) {
|
||||
// Fork workers.
|
||||
_.times(require('os').cpus().length, function(){
|
||||
cluster.fork();
|
||||
});
|
||||
|
||||
cluster.on('disconnect', function(worker, code, signal) {
|
||||
var w = cluster.fork(); // replace the dead worker
|
||||
logging.info('[%s] [master:%s] worker:%s disconnect! new worker:%s fork', new Date(), process.pid, worker.process.pid, w.process.pid);
|
||||
});
|
||||
|
||||
} else {
|
||||
require('coffee-script'); // remove this once we've fully converted over
|
||||
var express = require("express");
|
||||
var http = require("http");
|
||||
var path = require("path");
|
||||
var domainMiddleware = require('domain-middleware');
|
||||
var swagger = require("swagger-node-express");
|
||||
|
||||
var middleware = require('./middleware');
|
||||
|
|
@ -91,13 +77,7 @@ if (cluster.isMaster && (isDev || isProd)) {
|
|||
|
||||
// ------------ Server Configuration ------------
|
||||
|
||||
domainMiddleware({
|
||||
server: server,
|
||||
killTimeout: 3000
|
||||
}),
|
||||
|
||||
app.set("port", nconf.get('PORT'));
|
||||
|
||||
middleware.apiThrottle(app);
|
||||
if (!isProd) app.use(express.logger("dev"));
|
||||
app.use(express.compress());
|
||||
|
|
@ -125,11 +105,6 @@ if (cluster.isMaster && (isDev || isProd)) {
|
|||
app.use(express['static'](path.join(__dirname, "/../build"), { maxAge: maxAge }));
|
||||
app.use(express['static'](path.join(__dirname, "/../public")));
|
||||
|
||||
// development only
|
||||
//if ("development" === app.get("env")) {
|
||||
// app.use(express.errorHandler());
|
||||
//}
|
||||
|
||||
// Custom Directives
|
||||
app.use(require('./routes/pages').middleware);
|
||||
app.use(require('./routes/auth').middleware);
|
||||
|
|
@ -137,16 +112,12 @@ if (cluster.isMaster && (isDev || isProd)) {
|
|||
app.use('/api/v2', v2);
|
||||
app.use('/api/v1', require('./routes/apiv1').middleware);
|
||||
app.use('/export', require('./routes/dataexport').middleware);
|
||||
|
||||
app.use(utils.crashWorker(server,mongoose));
|
||||
app.use(utils.errorHandler);
|
||||
|
||||
require('./routes/apiv2.coffee')(swagger, v2);
|
||||
app.use(middleware.errorHandler);
|
||||
|
||||
server.on('request', app);
|
||||
server.listen(app.get("port"), function() {
|
||||
return logging.info("Express server listening on port " + app.get("port"));
|
||||
});
|
||||
|
||||
module.exports = server;
|
||||
}
|
||||
module.exports = server;
|
||||
38
src/utils.js
38
src/utils.js
|
|
@ -2,7 +2,6 @@ var nodemailer = require('nodemailer');
|
|||
var nconf = require('nconf');
|
||||
var crypto = require('crypto');
|
||||
var path = require("path");
|
||||
var cluster = require("cluster");
|
||||
|
||||
module.exports.sendEmail = function(mailData) {
|
||||
var smtpTransport = nodemailer.createTransport("SMTP",{
|
||||
|
|
@ -46,39 +45,4 @@ module.exports.setupConfig = function(){
|
|||
Error.stackTraceLimit = Infinity;
|
||||
if (nconf.get('NODE_ENV') === 'production')
|
||||
require('newrelic');
|
||||
};
|
||||
|
||||
module.exports.crashWorker = function(server,mongoose) {
|
||||
return function(err, req, res, next) {
|
||||
if (!cluster.isMaster) {
|
||||
// make sure we close down within 30 seconds
|
||||
var killtimer = setTimeout(function() {
|
||||
process.exit(1);
|
||||
}, 30000);
|
||||
// But don't keep the process open just for that!
|
||||
killtimer.unref();
|
||||
// stop taking new requests.
|
||||
server.close();
|
||||
mongoose.connection.close();
|
||||
cluster.worker.disconnect();
|
||||
}
|
||||
next(err);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
module.exports.errorHandler = function(err, req, res, next) {
|
||||
// when we hit an error, send it to admin as an email. If no ADMIN_EMAIL is present, just send it to yourself (SMTP_USER)
|
||||
var stack = (err.stack ? err.stack : err.message ? err.message : err) +
|
||||
"\n ----------------------------\n" +
|
||||
"\n\noriginalUrl: " + req.originalUrl +
|
||||
"\n\nauth: " + req.headers['x-api-user'] + ' | ' + req.headers['x-api-key'] +
|
||||
"\n\nheaders: " + JSON.stringify(req.headers) +
|
||||
"\n\nbody: " + JSON.stringify(req.body) +
|
||||
(res.locals.ops ? "\n\ncompleted ops: " + JSON.stringify(res.locals.ops) : "");
|
||||
var logging = require('./logging');
|
||||
logging.error(stack);
|
||||
var message = err.message ? err.message : err;
|
||||
message = (message.length < 200) ? message : message.substring(0,100) + message.substring(message.length-100,message.length);
|
||||
res.json(500,{err:message}); //res.end(err.message);
|
||||
}
|
||||
};
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
table.table.table-striped
|
||||
tr
|
||||
td
|
||||
a(target='_blank', href='http://habitrpg.wikia.com/wiki/Board:Looking_for_a_Group_(LFG)')=env.t('lfgPosts')
|
||||
a(target='_blank', href='http://habitrpg.wikia.com/wiki/Board:The_Archery_-_LFG')=env.t('lfgPosts')
|
||||
tr
|
||||
td
|
||||
a(target='_blank', href='https://vimeo.com/57654086')=env.t('tutorial')
|
||||
|
|
|
|||
Loading…
Reference in a new issue