index.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { defineIntegration, convertIntegrationFnToClass, SDK_VERSION, getActiveTransaction, captureException, continueTrace, startTransaction, getCurrentScope, spanToTraceHeader, getDynamicSamplingContextFromSpan, setHttpStatus } from '@sentry/core';
  2. import { fill, dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils';
  3. function isResponseObject(response) {
  4. return response && (response ).statusCode !== undefined;
  5. }
  6. function isBoomObject(response) {
  7. return response && (response ).isBoom !== undefined;
  8. }
  9. function isErrorEvent(event) {
  10. return event && (event ).error !== undefined;
  11. }
  12. function sendErrorToSentry(errorData) {
  13. captureException(errorData, {
  14. mechanism: {
  15. type: 'hapi',
  16. handled: false,
  17. data: {
  18. function: 'hapiErrorPlugin',
  19. },
  20. },
  21. });
  22. }
  23. const hapiErrorPlugin = {
  24. name: 'SentryHapiErrorPlugin',
  25. version: SDK_VERSION,
  26. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  27. register: async function (serverArg) {
  28. const server = serverArg ;
  29. server.events.on('request', (request, event) => {
  30. // eslint-disable-next-line deprecation/deprecation
  31. const transaction = getActiveTransaction();
  32. if (request.response && isBoomObject(request.response)) {
  33. sendErrorToSentry(request.response);
  34. } else if (isErrorEvent(event)) {
  35. sendErrorToSentry(event.error);
  36. }
  37. if (transaction) {
  38. transaction.setStatus('internal_error');
  39. transaction.end();
  40. }
  41. });
  42. },
  43. };
  44. const hapiTracingPlugin = {
  45. name: 'SentryHapiTracingPlugin',
  46. version: SDK_VERSION,
  47. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  48. register: async function (serverArg) {
  49. const server = serverArg ;
  50. server.ext('onPreHandler', (request, h) => {
  51. const transaction = continueTrace(
  52. {
  53. sentryTrace: request.headers['sentry-trace'] || undefined,
  54. baggage: request.headers['baggage'] || undefined,
  55. },
  56. transactionContext => {
  57. // eslint-disable-next-line deprecation/deprecation
  58. return startTransaction({
  59. ...transactionContext,
  60. op: 'hapi.request',
  61. name: request.route.path,
  62. description: `${request.route.method} ${request.path}`,
  63. });
  64. },
  65. );
  66. // eslint-disable-next-line deprecation/deprecation
  67. getCurrentScope().setSpan(transaction);
  68. return h.continue;
  69. });
  70. server.ext('onPreResponse', (request, h) => {
  71. // eslint-disable-next-line deprecation/deprecation
  72. const transaction = getActiveTransaction();
  73. if (request.response && isResponseObject(request.response) && transaction) {
  74. const response = request.response ;
  75. response.header('sentry-trace', spanToTraceHeader(transaction));
  76. const dynamicSamplingContext = dynamicSamplingContextToSentryBaggageHeader(
  77. getDynamicSamplingContextFromSpan(transaction),
  78. );
  79. if (dynamicSamplingContext) {
  80. response.header('baggage', dynamicSamplingContext);
  81. }
  82. }
  83. return h.continue;
  84. });
  85. server.ext('onPostHandler', (request, h) => {
  86. // eslint-disable-next-line deprecation/deprecation
  87. const transaction = getActiveTransaction();
  88. if (transaction) {
  89. if (request.response && isResponseObject(request.response)) {
  90. setHttpStatus(transaction, request.response.statusCode);
  91. }
  92. transaction.end();
  93. }
  94. return h.continue;
  95. });
  96. },
  97. };
  98. const INTEGRATION_NAME = 'Hapi';
  99. const _hapiIntegration = ((options = {}) => {
  100. const server = options.server ;
  101. return {
  102. name: INTEGRATION_NAME,
  103. setupOnce() {
  104. if (!server) {
  105. return;
  106. }
  107. fill(server, 'start', (originalStart) => {
  108. return async function () {
  109. await this.register(hapiTracingPlugin);
  110. await this.register(hapiErrorPlugin);
  111. const result = originalStart.apply(this);
  112. return result;
  113. };
  114. });
  115. },
  116. };
  117. }) ;
  118. const hapiIntegration = defineIntegration(_hapiIntegration);
  119. /**
  120. * Hapi Framework Integration.
  121. * @deprecated Use `hapiIntegration()` instead.
  122. */
  123. // eslint-disable-next-line deprecation/deprecation
  124. const Hapi = convertIntegrationFnToClass(INTEGRATION_NAME, hapiIntegration);
  125. // eslint-disable-next-line deprecation/deprecation
  126. export { Hapi, hapiErrorPlugin, hapiIntegration, hapiTracingPlugin };
  127. //# sourceMappingURL=index.js.map