index.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. Object.defineProperty(exports, '__esModule', { value: true });
  2. const core = require('@sentry/core');
  3. const utils = require('@sentry/utils');
  4. const DEFAULT_TRANSPORT_BUFFER_SIZE = 30;
  5. /**
  6. * This is a modified promise buffer that collects tasks until drain is called.
  7. * We need this in the edge runtime because edge function invocations may not share I/O objects, like fetch requests
  8. * and responses, and the normal PromiseBuffer inherently buffers stuff inbetween incoming requests.
  9. *
  10. * A limitation we need to be aware of is that DEFAULT_TRANSPORT_BUFFER_SIZE is the maximum amount of payloads the
  11. * SDK can send for a given edge function invocation.
  12. */
  13. class IsolatedPromiseBuffer {
  14. // We just have this field because the promise buffer interface requires it.
  15. // If we ever remove it from the interface we should also remove it here.
  16. constructor(_bufferSize = DEFAULT_TRANSPORT_BUFFER_SIZE) {
  17. this.$ = [];
  18. this._taskProducers = [];
  19. this._bufferSize = _bufferSize;
  20. }
  21. /**
  22. * @inheritdoc
  23. */
  24. add(taskProducer) {
  25. if (this._taskProducers.length >= this._bufferSize) {
  26. return Promise.reject(new utils.SentryError('Not adding Promise because buffer limit was reached.'));
  27. }
  28. this._taskProducers.push(taskProducer);
  29. return Promise.resolve();
  30. }
  31. /**
  32. * @inheritdoc
  33. */
  34. drain(timeout) {
  35. const oldTaskProducers = [...this._taskProducers];
  36. this._taskProducers = [];
  37. return new Promise(resolve => {
  38. const timer = setTimeout(() => {
  39. if (timeout && timeout > 0) {
  40. resolve(false);
  41. }
  42. }, timeout);
  43. // This cannot reject
  44. // eslint-disable-next-line @typescript-eslint/no-floating-promises
  45. Promise.all(
  46. oldTaskProducers.map(taskProducer =>
  47. taskProducer().then(null, () => {
  48. // catch all failed requests
  49. }),
  50. ),
  51. ).then(() => {
  52. // resolve to true if all fetch requests settled
  53. clearTimeout(timer);
  54. resolve(true);
  55. });
  56. });
  57. }
  58. }
  59. /**
  60. * Creates a Transport that uses the Edge Runtimes native fetch API to send events to Sentry.
  61. */
  62. function makeEdgeTransport(options) {
  63. function makeRequest(request) {
  64. const requestOptions = {
  65. body: request.body,
  66. method: 'POST',
  67. headers: options.headers,
  68. ...options.fetchOptions,
  69. };
  70. return fetch(options.url, requestOptions).then(response => {
  71. return {
  72. statusCode: response.status,
  73. headers: {
  74. 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
  75. 'retry-after': response.headers.get('Retry-After'),
  76. },
  77. };
  78. });
  79. }
  80. return core.createTransport(options, makeRequest, new IsolatedPromiseBuffer(options.bufferSize));
  81. }
  82. exports.IsolatedPromiseBuffer = IsolatedPromiseBuffer;
  83. exports.makeEdgeTransport = makeEdgeTransport;
  84. //# sourceMappingURL=index.js.map