hydrateBreadcrumbs.tsx 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import invariant from 'invariant';
  2. import {BreadcrumbType} from 'sentry/types/breadcrumbs';
  3. import isValidDate from 'sentry/utils/date/isValidDate';
  4. import type {BreadcrumbFrame, RawBreadcrumbFrame} from 'sentry/utils/replays/types';
  5. import type {ReplayRecord} from 'sentry/views/replays/types';
  6. function isBreadcrumbFrame(frame: BreadcrumbFrame | undefined): frame is BreadcrumbFrame {
  7. return frame !== undefined;
  8. }
  9. export default function hydrateBreadcrumbs(
  10. replayRecord: ReplayRecord,
  11. breadcrumbFrames: RawBreadcrumbFrame[]
  12. ): BreadcrumbFrame[] {
  13. const startTimestampMs = replayRecord.started_at.getTime();
  14. return breadcrumbFrames
  15. .map((frame: RawBreadcrumbFrame) => {
  16. try {
  17. const time = new Date(frame.timestamp * 1000);
  18. invariant(isValidDate(time), 'breadcrumbFrame.timestamp is invalid');
  19. return {
  20. ...frame,
  21. offsetMs: Math.abs(time.getTime() - startTimestampMs),
  22. timestamp: time,
  23. timestampMs: time.getTime(),
  24. };
  25. } catch {
  26. return undefined;
  27. }
  28. })
  29. .filter(isBreadcrumbFrame);
  30. }
  31. export function replayInitBreadcrumb(replayRecord: ReplayRecord): BreadcrumbFrame {
  32. const initialUrl = replayRecord.urls?.[0] ?? replayRecord.tags.url?.join(', ');
  33. return {
  34. category: 'replay.init',
  35. message: initialUrl,
  36. offsetMs: 0,
  37. timestamp: replayRecord.started_at,
  38. timestampMs: replayRecord.started_at.getTime(),
  39. type: BreadcrumbType.INIT, // For compatibility reasons. See BreadcrumbType
  40. };
  41. }