2015-02-10 19:41:24 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
var domain = require("domain");
|
|
|
|
var url = require("url");
|
|
|
|
var _ = require("lodash");
|
|
|
|
|
2015-10-23 13:20:05 +00:00
|
|
|
plugin.consumes = ["raygun", "connect", "http", "connect.remote-address", "metrics"];
|
2015-02-10 19:41:24 +00:00
|
|
|
plugin.provides = ["raygun.connect"];
|
|
|
|
|
|
|
|
module.exports = plugin;
|
|
|
|
|
|
|
|
function plugin(options, imports, register) {
|
|
|
|
var raygun = imports.raygun;
|
|
|
|
var errorClient = raygun.errorClient;
|
|
|
|
var warningClient = raygun.warningClient;
|
|
|
|
var connect = imports.connect;
|
|
|
|
var server = imports.http.getServer();
|
2015-10-23 13:20:05 +00:00
|
|
|
var metrics = imports.metrics;
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
errorClient.user = warningClient.user = function(req) {
|
|
|
|
return (req && req.user) ? req.user.name : "";
|
|
|
|
};
|
|
|
|
|
|
|
|
connect.useStart(function(req, res, next) {
|
|
|
|
var d = domain.create();
|
|
|
|
d.on("error", function(err) {
|
2015-07-24 10:33:41 +00:00
|
|
|
raygun.customData = raygun.customData || {};
|
|
|
|
raygun.customData.serverCrashed = true;
|
|
|
|
raygun.customData.exceptionStack = err.stack;
|
|
|
|
raygun.customData.crashStack = new Error().stack;
|
2015-05-13 11:01:04 +00:00
|
|
|
sendRequestError(err, req);
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
// from http://nodejs.org/api/domain.html
|
|
|
|
try {
|
|
|
|
// make sure we close down within 10 seconds
|
|
|
|
console.error("Uncaught exception. Logging error and shutting down in 10 sec");
|
2015-07-24 10:23:12 +00:00
|
|
|
console.error("Exception:", err);
|
|
|
|
console.error("Exception stack:", err.stack);
|
|
|
|
console.error("Our current stack: ", new Error().stack);
|
2015-02-10 19:41:24 +00:00
|
|
|
var killtimer = setTimeout(function() {
|
|
|
|
console.error("Exiting after uncaught exception");
|
|
|
|
process.exit(1);
|
|
|
|
}, 10000);
|
|
|
|
// But don't keep the process open just for that!
|
|
|
|
killtimer.unref();
|
|
|
|
|
|
|
|
// stop taking new requests.
|
|
|
|
server.close();
|
|
|
|
next(err);
|
|
|
|
} catch (er2) {
|
|
|
|
console.error("Error sending 500!", er2.stack);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
d.add(req);
|
|
|
|
d.add(res);
|
|
|
|
d.run(next);
|
|
|
|
});
|
|
|
|
|
|
|
|
server.on("timeout", function(socket) {
|
|
|
|
socket.destroy();
|
|
|
|
|
|
|
|
var domain = socket._httpMessage && socket._httpMessage.domain;
|
|
|
|
var req = domain && domain.members[0];
|
2015-10-30 14:27:04 +00:00
|
|
|
if (req && req.url)
|
2015-05-13 11:01:04 +00:00
|
|
|
sendRequestWarning(new Error("Request timed out: " + req.url), req);
|
2015-02-10 19:41:24 +00:00
|
|
|
});
|
|
|
|
|
2015-05-13 11:01:04 +00:00
|
|
|
function sendRequestError(err, req) {
|
|
|
|
return _sendRequest(errorClient, err, req);
|
|
|
|
}
|
|
|
|
|
|
|
|
function sendRequestWarning(err, req) {
|
|
|
|
return _sendRequest(warningClient, err, req);
|
|
|
|
}
|
|
|
|
|
|
|
|
function _sendRequest(raygunClient, err, req) {
|
2015-02-10 19:41:24 +00:00
|
|
|
var parsedUrl = url.parse(req.url, false);
|
|
|
|
var ip = req.remoteAddress;
|
|
|
|
|
|
|
|
var customData = _.clone(raygun.customData || {});
|
|
|
|
if (req.user) {
|
|
|
|
customData.user = {
|
|
|
|
id: req.user.id,
|
|
|
|
name: req.user.name,
|
|
|
|
email: req.user.email
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else if (req.session) {
|
|
|
|
customData.user = {
|
|
|
|
id: req.session.uid
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
raygunClient.send(err, customData, function() {}, {
|
|
|
|
host: parsedUrl.hostname,
|
|
|
|
path: parsedUrl.pathname,
|
|
|
|
method: req.method,
|
|
|
|
ip: ip,
|
|
|
|
query: parsedUrl.query,
|
|
|
|
headers: req.headers,
|
|
|
|
body: req.body,
|
|
|
|
user: req.user
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
register(null, {"raygun.connect": {
|
2015-05-13 11:01:04 +00:00
|
|
|
sendRequestError: sendRequestError,
|
|
|
|
sendRequestWarning: sendRequestWarning
|
2015-02-10 19:41:24 +00:00
|
|
|
}});
|
2015-07-24 13:34:46 +00:00
|
|
|
}
|