client.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { BaseClient, applySdkMetadata } from '@sentry/core';
  2. import { getSDKSource, logger, createClientReportEnvelope, dsnToString } from '@sentry/utils';
  3. import { DEBUG_BUILD } from './debug-build.js';
  4. import { eventFromException, eventFromMessage } from './eventbuilder.js';
  5. import { WINDOW } from './helpers.js';
  6. import { createUserFeedbackEnvelope } from './userfeedback.js';
  7. /**
  8. * Configuration options for the Sentry Browser SDK.
  9. * @see @sentry/types Options for more information.
  10. */
  11. /**
  12. * The Sentry Browser SDK Client.
  13. *
  14. * @see BrowserOptions for documentation on configuration options.
  15. * @see SentryClient for usage documentation.
  16. */
  17. class BrowserClient extends BaseClient {
  18. /**
  19. * Creates a new Browser SDK instance.
  20. *
  21. * @param options Configuration options for this SDK.
  22. */
  23. constructor(options) {
  24. const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();
  25. applySdkMetadata(options, 'browser', ['browser'], sdkSource);
  26. super(options);
  27. if (options.sendClientReports && WINDOW.document) {
  28. WINDOW.document.addEventListener('visibilitychange', () => {
  29. if (WINDOW.document.visibilityState === 'hidden') {
  30. this._flushOutcomes();
  31. }
  32. });
  33. }
  34. }
  35. /**
  36. * @inheritDoc
  37. */
  38. eventFromException(exception, hint) {
  39. return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);
  40. }
  41. /**
  42. * @inheritDoc
  43. */
  44. eventFromMessage(
  45. message,
  46. // eslint-disable-next-line deprecation/deprecation
  47. level = 'info',
  48. hint,
  49. ) {
  50. return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);
  51. }
  52. /**
  53. * Sends user feedback to Sentry.
  54. */
  55. captureUserFeedback(feedback) {
  56. if (!this._isEnabled()) {
  57. DEBUG_BUILD && logger.warn('SDK not enabled, will not capture user feedback.');
  58. return;
  59. }
  60. const envelope = createUserFeedbackEnvelope(feedback, {
  61. metadata: this.getSdkMetadata(),
  62. dsn: this.getDsn(),
  63. tunnel: this.getOptions().tunnel,
  64. });
  65. // _sendEnvelope should not throw
  66. // eslint-disable-next-line @typescript-eslint/no-floating-promises
  67. this._sendEnvelope(envelope);
  68. }
  69. /**
  70. * @inheritDoc
  71. */
  72. _prepareEvent(event, hint, scope) {
  73. event.platform = event.platform || 'javascript';
  74. return super._prepareEvent(event, hint, scope);
  75. }
  76. /**
  77. * Sends client reports as an envelope.
  78. */
  79. _flushOutcomes() {
  80. const outcomes = this._clearOutcomes();
  81. if (outcomes.length === 0) {
  82. DEBUG_BUILD && logger.log('No outcomes to send');
  83. return;
  84. }
  85. // This is really the only place where we want to check for a DSN and only send outcomes then
  86. if (!this._dsn) {
  87. DEBUG_BUILD && logger.log('No dsn provided, will not send outcomes');
  88. return;
  89. }
  90. DEBUG_BUILD && logger.log('Sending outcomes:', outcomes);
  91. const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn));
  92. // _sendEnvelope should not throw
  93. // eslint-disable-next-line @typescript-eslint/no-floating-promises
  94. this._sendEnvelope(envelope);
  95. }
  96. }
  97. export { BrowserClient };
  98. //# sourceMappingURL=client.js.map