Просмотр исходного кода

fix(analytics): throwing errors on unexisting users

Karol Sójko 1 год назад
Родитель
Сommit
c511f259c7

+ 5 - 1
packages/analytics/src/Domain/Handler/PaymentFailedEventHandler.ts

@@ -17,7 +17,11 @@ export class PaymentFailedEventHandler implements DomainEventHandlerInterface {
   ) {}
 
   async handle(event: PaymentFailedEvent): Promise<void> {
-    const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.PaymentFailed], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 1
packages/analytics/src/Domain/Handler/PaymentSuccessEventHandler.ts

@@ -88,7 +88,11 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
   ) {}
 
   async handle(event: PaymentSuccessEvent): Promise<void> {
-    const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.PaymentSuccess], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 2
packages/analytics/src/Domain/Handler/RefundProcessedEventHandler.ts

@@ -17,8 +17,11 @@ export class RefundProcessedEventHandler implements DomainEventHandlerInterface
   ) {}
 
   async handle(event: RefundProcessedEvent): Promise<void> {
-    const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
-
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId } = analyticsMetadataOrError.getValue()
     await this.statisticsStore.incrementMeasure(StatisticMeasureName.NAMES.Refunds, event.payload.amount, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 1
packages/analytics/src/Domain/Handler/SessionCreatedEventHandler.ts

@@ -13,7 +13,11 @@ export class SessionCreatedEventHandler implements DomainEventHandlerInterface {
   ) {}
 
   async handle(event: SessionCreatedEvent): Promise<void> {
-    const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: event.payload.userUuid })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userUuid: event.payload.userUuid })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId } = analyticsMetadataOrError.getValue()
 
     if (this.mixpanelClient !== null) {
       this.mixpanelClient.track(event.type, {

+ 5 - 1
packages/analytics/src/Domain/Handler/SessionRefreshedEventHandler.ts

@@ -13,7 +13,11 @@ export class SessionRefreshedEventHandler implements DomainEventHandlerInterface
   ) {}
 
   async handle(event: SessionRefreshedEvent): Promise<void> {
-    const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: event.payload.userUuid })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userUuid: event.payload.userUuid })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId } = analyticsMetadataOrError.getValue()
 
     if (this.mixpanelClient !== null) {
       this.mixpanelClient.track(event.type, {

+ 5 - 1
packages/analytics/src/Domain/Handler/SubscriptionCancelledEventHandler.ts

@@ -29,7 +29,11 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
   ) {}
 
   async handle(event: SubscriptionCancelledEvent): Promise<void> {
-    const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId, userUuid } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 1
packages/analytics/src/Domain/Handler/SubscriptionExpiredEventHandler.ts

@@ -27,7 +27,11 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
   ) {}
 
   async handle(event: SubscriptionExpiredEvent): Promise<void> {
-    const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId, userUuid } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity(
       [AnalyticsActivity.SubscriptionExpired, AnalyticsActivity.ExistingCustomersChurn],
       analyticsId,

+ 5 - 1
packages/analytics/src/Domain/Handler/SubscriptionPurchasedEventHandler.ts

@@ -29,7 +29,11 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
   ) {}
 
   async handle(event: SubscriptionPurchasedEvent): Promise<void> {
-    const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId, userUuid } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionPurchased], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 1
packages/analytics/src/Domain/Handler/SubscriptionReactivatedEventHandler.ts

@@ -19,7 +19,11 @@ export class SubscriptionReactivatedEventHandler implements DomainEventHandlerIn
   ) {}
 
   async handle(event: SubscriptionReactivatedEvent): Promise<void> {
-    const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionReactivated], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 1
packages/analytics/src/Domain/Handler/SubscriptionRefundedEventHandler.ts

@@ -27,7 +27,11 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
   ) {}
 
   async handle(event: SubscriptionRefundedEvent): Promise<void> {
-    const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId, userUuid } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRefunded], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 5 - 1
packages/analytics/src/Domain/Handler/SubscriptionRenewedEventHandler.ts

@@ -26,7 +26,11 @@ export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterf
   ) {}
 
   async handle(event: SubscriptionRenewedEvent): Promise<void> {
-    const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    const analyticsMetadataOrError = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
+    if (analyticsMetadataOrError.isFailed()) {
+      return
+    }
+    const { analyticsId, userUuid } = analyticsMetadataOrError.getValue()
     await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRenewed], analyticsId, [
       Period.Today,
       Period.ThisWeek,

+ 4 - 9
packages/analytics/src/Domain/UseCase/GetUserAnalyticsId/GetUserAnalyticsId.spec.ts

@@ -24,23 +24,18 @@ describe('GetUserAnalyticsId', () => {
   })
 
   it('should return analytics id for a user by uuid', async () => {
-    expect((await createUseCase().execute({ userUuid: '1-2-3' })).analyticsId).toEqual(123)
+    expect((await createUseCase().execute({ userUuid: '1-2-3' })).getValue().analyticsId).toEqual(123)
   })
 
   it('should return analytics id for a user by email', async () => {
-    expect((await createUseCase().execute({ userEmail: 'test@test.te' })).analyticsId).toEqual(123)
+    expect((await createUseCase().execute({ userEmail: 'test@test.te' })).getValue().analyticsId).toEqual(123)
   })
 
   it('should throw error if user is missing analytics entity', async () => {
     analyticsEntityRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
-    let error = null
 
-    try {
-      await createUseCase().execute({ userUuid: '1-2-3' })
-    } catch (caughtError) {
-      error = caughtError
-    }
+    const result = await createUseCase().execute({ userUuid: '1-2-3' })
 
-    expect(error).not.toBeNull()
+    expect(result.isFailed()).toEqual(true)
   })
 })

+ 6 - 7
packages/analytics/src/Domain/UseCase/GetUserAnalyticsId/GetUserAnalyticsId.ts

@@ -1,19 +1,18 @@
 import { inject, injectable } from 'inversify'
-import { Username, Uuid } from '@standardnotes/domain-core'
+import { Result, UseCaseInterface, Username, Uuid } from '@standardnotes/domain-core'
 
 import TYPES from '../../../Bootstrap/Types'
 import { AnalyticsEntityRepositoryInterface } from '../../Entity/AnalyticsEntityRepositoryInterface'
-import { UseCaseInterface } from '../UseCaseInterface'
 import { GetUserAnalyticsIdDTO } from './GetUserAnalyticsIdDTO'
 import { GetUserAnalyticsIdResponse } from './GetUserAnalyticsIdResponse'
 
 @injectable()
-export class GetUserAnalyticsId implements UseCaseInterface {
+export class GetUserAnalyticsId implements UseCaseInterface<GetUserAnalyticsIdResponse> {
   constructor(
     @inject(TYPES.AnalyticsEntityRepository) private analyticsEntityRepository: AnalyticsEntityRepositoryInterface,
   ) {}
 
-  async execute(dto: GetUserAnalyticsIdDTO): Promise<GetUserAnalyticsIdResponse> {
+  async execute(dto: GetUserAnalyticsIdDTO): Promise<Result<GetUserAnalyticsIdResponse>> {
     let analyticsEntity = null
     if (dto.userUuid) {
       analyticsEntity = await this.analyticsEntityRepository.findOneByUserUuid(dto.userUuid)
@@ -22,13 +21,13 @@ export class GetUserAnalyticsId implements UseCaseInterface {
     }
 
     if (analyticsEntity === null) {
-      throw new Error(`Could not find analytics entity for user ${dto.userUuid}`)
+      return Result.fail(`Could not find analytics entity ${dto.userUuid}`)
     }
 
-    return {
+    return Result.ok({
       analyticsId: analyticsEntity.id,
       userUuid: Uuid.create(analyticsEntity.userUuid).getValue(),
       username: Username.create(analyticsEntity.username).getValue(),
-    }
+    })
   }
 }