PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/node_modules/newrelic/test/error.test.js

https://github.com/hayes/framework
JavaScript | 297 lines | 214 code | 72 blank | 11 comment | 4 complexity | 16441e4226b2bea6205c7318e7296e14 MD5 | raw file
Possible License(s): MIT, MPL-2.0-no-copyleft-exception
  1. 'use strict';
  2. var path = require('path')
  3. , chai = require('chai')
  4. , expect = chai.expect
  5. , should = chai.should()
  6. , helper = require(path.join(__dirname, 'lib', 'agent_helper'))
  7. , config = require(path.join(__dirname, '..', 'lib', 'config.default'))
  8. , dominion = require(path.join(__dirname, '..', 'lib', 'dominion'))
  9. , ErrorTracer = require(path.join(__dirname, '..', 'lib', 'error'))
  10. , Transaction = require(path.join(__dirname, '..', 'lib', 'transaction'))
  11. ;
  12. function createTransaction(code) {
  13. return { statusCode : code, exceptions : [] };
  14. }
  15. describe("ErrorTracer", function () {
  16. var service;
  17. beforeEach(function () {
  18. service = new ErrorTracer(config.config);
  19. });
  20. it("shouldn't gather errors if it's switched off", function () {
  21. var error = new Error('this error will never be seen');
  22. service.config.error_collector.enabled = false;
  23. expect(service.errorCount).equal(0);
  24. expect(service.errors.length).equal(0);
  25. service.add(error);
  26. expect(service.errorCount).equal(1);
  27. expect(service.errors.length).equal(0);
  28. service.config.error_collector.enabled = true;
  29. });
  30. it("should retain a maximum of 20 errors to send", function () {
  31. for (var i = 0; i < 5; i++) service.add(null, new Error('filling the queue'));
  32. expect(service.errors.length).equal(5);
  33. for (i = 0; i < 5; i++) service.add(null, new Error('more filling the queue'));
  34. expect(service.errors.length).equal(10);
  35. // this will take the tracer 3 over the limit of 20
  36. for (i = 0; i < 13; i++) service.add(null, new Error('overfilling the queue'));
  37. expect(service.errorCount).equal(23);
  38. expect(service.errors.length).equal(20);
  39. });
  40. it("should handle errors properly for transactions", function () {
  41. service.onTransactionFinished(createTransaction(400));
  42. service.onTransactionFinished(createTransaction(500));
  43. expect(service.errors.length).equal(2);
  44. expect(service.errorCount).equal(2);
  45. });
  46. it("should ignore 404 errors for transactions", function () {
  47. service.onTransactionFinished(createTransaction(400));
  48. // 404 errors are ignored by default
  49. service.onTransactionFinished(createTransaction(404));
  50. service.onTransactionFinished(createTransaction(404));
  51. service.onTransactionFinished(createTransaction(404));
  52. service.onTransactionFinished(createTransaction(404));
  53. expect(service.errorCount).equal(1);
  54. });
  55. describe("with an internal server error (500) and an exception", function () {
  56. var agent
  57. , scope
  58. , error
  59. ;
  60. beforeEach(function () {
  61. agent = helper.loadMockedAgent();
  62. service = agent.errors;
  63. var transaction = new Transaction(agent)
  64. , exception = new Error('500 test error')
  65. ;
  66. transaction.exceptions.push(exception);
  67. scope = transaction.measureWeb('/test-request/zxrkbl', 500, 5, 5);
  68. transaction.end();
  69. error = service.errors[0];
  70. });
  71. afterEach(function () {
  72. helper.unloadAgent(agent);
  73. });
  74. it("should properly reset when finished", function () {
  75. expect(service.errorCount).equal(1);
  76. service.clear();
  77. expect(service.errorCount).equal(0);
  78. });
  79. it("should associate errors with the transaction's scope", function () {
  80. var errorScope = error[1];
  81. expect(errorScope).equal(scope);
  82. });
  83. it("should associate errors with a message", function () {
  84. var message = error[2];
  85. expect(message).match(/500 test error/);
  86. });
  87. it("should associate errors with a message class", function () {
  88. var messageClass = error[3];
  89. expect(messageClass).equal('Error');
  90. });
  91. it("should associate errors with parameters", function () {
  92. var params = error[4];
  93. expect(params).eql({request_uri : "/test-request/zxrkbl"});
  94. });
  95. });
  96. describe("with a service unavailable (503) error", function () {
  97. var agent
  98. , scope
  99. , error
  100. ;
  101. beforeEach(function () {
  102. agent = helper.loadMockedAgent();
  103. service = agent.errors;
  104. var transaction = new Transaction(agent);
  105. scope = transaction.measureWeb('/test-request/zxrkbl', 503, 5, 5);
  106. transaction.end();
  107. error = service.errors[0];
  108. });
  109. afterEach(function () {
  110. helper.unloadAgent(agent);
  111. });
  112. it("should properly reset when finished", function () {
  113. expect(service.errorCount).equal(1);
  114. service.clear();
  115. expect(service.errorCount).equal(0);
  116. });
  117. it("should associate errors with the transaction's scope", function () {
  118. var errorScope = error[1];
  119. expect(errorScope).equal(scope);
  120. });
  121. it("should associate errors with a message", function () {
  122. var message = error[2];
  123. expect(message).equal('HttpError 503');
  124. });
  125. it("should associate errors with a message class", function () {
  126. var messageClass = error[3];
  127. expect(messageClass).equal('HttpError 503');
  128. });
  129. it("should associate errors with parameters", function () {
  130. var params = error[4];
  131. expect(params).deep.equal({request_uri : "/test-request/zxrkbl"});
  132. });
  133. });
  134. describe("when monitoring function application for errors", function () {
  135. var transaction;
  136. beforeEach(function () {
  137. var agent = helper.loadMockedAgent();
  138. transaction = new Transaction(agent);
  139. });
  140. it("should rethrow the exception", function () {
  141. var testFunction = function () {
  142. var uninitialized;
  143. uninitialized.explosion.happens.here = "fabulous";
  144. };
  145. expect(function () {
  146. service.monitor(testFunction, transaction);
  147. }).throws(TypeError);
  148. });
  149. it("should return the correct value", function () {
  150. var safeFunction = function (val) {
  151. return val * val;
  152. };
  153. expect(service.monitor(safeFunction.bind(null, 3), transaction)).equal(9);
  154. });
  155. });
  156. if (dominion.available) {
  157. describe("when domains are available", function () {
  158. var mochaHandlers
  159. , agent
  160. , domain
  161. , active
  162. , json
  163. ;
  164. before(function (done) {
  165. agent = helper.loadMockedAgent();
  166. /**
  167. * Mocha is extremely zealous about trapping errors, and runs each test
  168. * in a try / catch block. To get the exception to propagate out to the
  169. * domain's uncaughtException handler, we need to put the test in an
  170. * asynchronous context and break out of the mocha jail.
  171. */
  172. process.nextTick(function () {
  173. // disable mocha's error handler
  174. mochaHandlers = helper.onlyDomains();
  175. process.once('uncaughtException', function () {
  176. json = agent.errors.errors[0];
  177. return done();
  178. });
  179. var disruptor = agent.tracer.transactionProxy(function () {
  180. domain = agent.getTransaction().trace.domain;
  181. active = process.domain;
  182. // trigger the domain
  183. throw new Error('sample error');
  184. });
  185. disruptor();
  186. });
  187. });
  188. after(function () {
  189. // ...but be sure to re-enable mocha's error handler
  190. process._events['uncaughtException'] = mochaHandlers;
  191. });
  192. it("should put transactions in domains", function () {
  193. should.exist(domain);
  194. should.exist(active);
  195. expect(domain).equal(active);
  196. });
  197. it("should find a single error", function () {
  198. expect(agent.errors.errors.length).equal(1);
  199. });
  200. describe("when handed an error from a domain", function () {
  201. it("should find the error", function () {
  202. should.exist(json);
  203. });
  204. it("should have 5 elements in the trace", function () {
  205. expect(json.length).equal(5);
  206. });
  207. it("should always have a 0 (ignored) timestamp", function () {
  208. expect(json[0]).equal(0);
  209. });
  210. it("should have the default ('Unknown') scope", function () {
  211. expect(json[1]).equal('Unknown');
  212. });
  213. it("should have the error's message", function () {
  214. expect(json[2]).match(/^Error: sample error/);
  215. });
  216. it("should have the error's constructor name (class)", function () {
  217. expect(json[3]).equal('Error');
  218. });
  219. it("should default to empty parameters", function () {
  220. expect(json[4]).deep.equal({});
  221. });
  222. });
  223. });
  224. }
  225. });