From bea75c3395b902f7d3450ec2e295074ed110cd29 Mon Sep 17 00:00:00 2001 From: Wesley Finck Date: Wed, 29 Oct 2025 11:41:02 -0700 Subject: [PATCH] refactor: handle authentication errors in card and collection use cases and controllers Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) --- .../useCases/commands/CreateCollectionUseCase.ts | 9 +++++++-- .../useCases/commands/DeleteCollectionUseCase.ts | 9 +++++++-- .../useCases/commands/UpdateCollectionUseCase.ts | 9 +++++++-- .../useCases/commands/UpdateNoteCardUseCase.ts | 9 +++++++-- .../http/controllers/CreateCollectionController.ts | 7 ++++++- .../http/controllers/DeleteCollectionController.ts | 7 ++++++- .../http/controllers/UpdateCollectionController.ts | 7 ++++++- .../http/controllers/UpdateNoteCardController.ts | 7 ++++++- 8 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/modules/cards/application/useCases/commands/CreateCollectionUseCase.ts b/src/modules/cards/application/useCases/commands/CreateCollectionUseCase.ts index de670353..5e6c8e7d 100644 --- a/src/modules/cards/application/useCases/commands/CreateCollectionUseCase.ts +++ b/src/modules/cards/application/useCases/commands/CreateCollectionUseCase.ts @@ -6,6 +6,7 @@ import { ICollectionRepository } from '../../../domain/ICollectionRepository'; import { Collection, CollectionAccessType } from '../../../domain/Collection'; import { CuratorId } from '../../../domain/value-objects/CuratorId'; import { ICollectionPublisher } from '../../ports/ICollectionPublisher'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export interface CreateCollectionDTO { name: string; @@ -29,7 +30,7 @@ export class CreateCollectionUseCase CreateCollectionDTO, Result< CreateCollectionResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { @@ -43,7 +44,7 @@ export class CreateCollectionUseCase ): Promise< Result< CreateCollectionResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { try { @@ -84,6 +85,10 @@ export class CreateCollectionUseCase // Publish collection const publishResult = await this.collectionPublisher.publish(collection); if (publishResult.isErr()) { + // Propagate authentication errors + if (publishResult.error instanceof AuthenticationError) { + return err(publishResult.error); + } return err( new ValidationError( `Failed to publish collection: ${publishResult.error.message}`, diff --git a/src/modules/cards/application/useCases/commands/DeleteCollectionUseCase.ts b/src/modules/cards/application/useCases/commands/DeleteCollectionUseCase.ts index 52ae3bef..facc9082 100644 --- a/src/modules/cards/application/useCases/commands/DeleteCollectionUseCase.ts +++ b/src/modules/cards/application/useCases/commands/DeleteCollectionUseCase.ts @@ -6,6 +6,7 @@ import { ICollectionRepository } from '../../../domain/ICollectionRepository'; import { CollectionId } from '../../../domain/value-objects/CollectionId'; import { CuratorId } from '../../../domain/value-objects/CuratorId'; import { ICollectionPublisher } from '../../ports/ICollectionPublisher'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export interface DeleteCollectionDTO { collectionId: string; @@ -28,7 +29,7 @@ export class DeleteCollectionUseCase DeleteCollectionDTO, Result< DeleteCollectionResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { @@ -42,7 +43,7 @@ export class DeleteCollectionUseCase ): Promise< Result< DeleteCollectionResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { try { @@ -99,6 +100,10 @@ export class DeleteCollectionUseCase collection.publishedRecordId, ); if (unpublishResult.isErr()) { + // Propagate authentication errors + if (unpublishResult.error instanceof AuthenticationError) { + return err(unpublishResult.error); + } return err( new ValidationError( `Failed to unpublish collection: ${unpublishResult.error.message}`, diff --git a/src/modules/cards/application/useCases/commands/UpdateCollectionUseCase.ts b/src/modules/cards/application/useCases/commands/UpdateCollectionUseCase.ts index d8e393e9..8aedd3bd 100644 --- a/src/modules/cards/application/useCases/commands/UpdateCollectionUseCase.ts +++ b/src/modules/cards/application/useCases/commands/UpdateCollectionUseCase.ts @@ -8,6 +8,7 @@ import { CuratorId } from '../../../domain/value-objects/CuratorId'; import { CollectionName } from '../../../domain/value-objects/CollectionName'; import { CollectionDescription } from '../../../domain/value-objects/CollectionDescription'; import { ICollectionPublisher } from '../../ports/ICollectionPublisher'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export interface UpdateCollectionDTO { collectionId: string; @@ -32,7 +33,7 @@ export class UpdateCollectionUseCase UpdateCollectionDTO, Result< UpdateCollectionResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { @@ -46,7 +47,7 @@ export class UpdateCollectionUseCase ): Promise< Result< UpdateCollectionResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { try { @@ -117,6 +118,10 @@ export class UpdateCollectionUseCase const republishResult = await this.collectionPublisher.publish(collection); if (republishResult.isErr()) { + // Propagate authentication errors + if (republishResult.error instanceof AuthenticationError) { + return err(republishResult.error); + } return err( new ValidationError( `Failed to republish collection: ${republishResult.error.message}`, diff --git a/src/modules/cards/application/useCases/commands/UpdateNoteCardUseCase.ts b/src/modules/cards/application/useCases/commands/UpdateNoteCardUseCase.ts index 174534d2..e416f4a3 100644 --- a/src/modules/cards/application/useCases/commands/UpdateNoteCardUseCase.ts +++ b/src/modules/cards/application/useCases/commands/UpdateNoteCardUseCase.ts @@ -8,6 +8,7 @@ import { CuratorId } from '../../../domain/value-objects/CuratorId'; import { CardTypeEnum } from '../../../domain/value-objects/CardType'; import { CardContent } from '../../../domain/value-objects/CardContent'; import { ICardPublisher } from '../../ports/ICardPublisher'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export interface UpdateNoteCardDTO { cardId: string; @@ -31,7 +32,7 @@ export class UpdateNoteCardUseCase UpdateNoteCardDTO, Result< UpdateNoteCardResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { @@ -45,7 +46,7 @@ export class UpdateNoteCardUseCase ): Promise< Result< UpdateNoteCardResponseDTO, - ValidationError | AppError.UnexpectedError + ValidationError | AuthenticationError | AppError.UnexpectedError > > { try { @@ -128,6 +129,10 @@ export class UpdateNoteCardUseCase card.publishedRecordId, ); if (publishResult.isErr()) { + // Propagate authentication errors + if (publishResult.error instanceof AuthenticationError) { + return err(publishResult.error); + } return err(AppError.UnexpectedError.create(publishResult.error)); } diff --git a/src/modules/cards/infrastructure/http/controllers/CreateCollectionController.ts b/src/modules/cards/infrastructure/http/controllers/CreateCollectionController.ts index 69d7a534..5de054ff 100644 --- a/src/modules/cards/infrastructure/http/controllers/CreateCollectionController.ts +++ b/src/modules/cards/infrastructure/http/controllers/CreateCollectionController.ts @@ -2,6 +2,7 @@ import { Controller } from '../../../../../shared/infrastructure/http/Controller import { Response } from 'express'; import { CreateCollectionUseCase } from '../../../application/useCases/commands/CreateCollectionUseCase'; import { AuthenticatedRequest } from '../../../../../shared/infrastructure/http/middleware/AuthMiddleware'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export class CreateCollectionController extends Controller { constructor(private createCollectionUseCase: CreateCollectionUseCase) { @@ -28,12 +29,16 @@ export class CreateCollectionController extends Controller { }); if (result.isErr()) { + // Check if the error is an authentication error + if (result.error instanceof AuthenticationError) { + return this.unauthorized(res, result.error.message); + } return this.fail(res, result.error); } return this.ok(res, result.value); } catch (error: any) { - return this.fail(res, error); + return this.handleError(res, error); } } } diff --git a/src/modules/cards/infrastructure/http/controllers/DeleteCollectionController.ts b/src/modules/cards/infrastructure/http/controllers/DeleteCollectionController.ts index e9a2d3d1..f35b75ce 100644 --- a/src/modules/cards/infrastructure/http/controllers/DeleteCollectionController.ts +++ b/src/modules/cards/infrastructure/http/controllers/DeleteCollectionController.ts @@ -2,6 +2,7 @@ import { Controller } from '../../../../../shared/infrastructure/http/Controller import { Response } from 'express'; import { DeleteCollectionUseCase } from '../../../application/useCases/commands/DeleteCollectionUseCase'; import { AuthenticatedRequest } from '../../../../../shared/infrastructure/http/middleware/AuthMiddleware'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export class DeleteCollectionController extends Controller { constructor(private deleteCollectionUseCase: DeleteCollectionUseCase) { @@ -27,12 +28,16 @@ export class DeleteCollectionController extends Controller { }); if (result.isErr()) { + // Check if the error is an authentication error + if (result.error instanceof AuthenticationError) { + return this.unauthorized(res, result.error.message); + } return this.fail(res, result.error); } return this.ok(res, result.value); } catch (error: any) { - return this.fail(res, error); + return this.handleError(res, error); } } } diff --git a/src/modules/cards/infrastructure/http/controllers/UpdateCollectionController.ts b/src/modules/cards/infrastructure/http/controllers/UpdateCollectionController.ts index 26bc8509..dbd4dc71 100644 --- a/src/modules/cards/infrastructure/http/controllers/UpdateCollectionController.ts +++ b/src/modules/cards/infrastructure/http/controllers/UpdateCollectionController.ts @@ -2,6 +2,7 @@ import { Controller } from '../../../../../shared/infrastructure/http/Controller import { Response } from 'express'; import { UpdateCollectionUseCase } from '../../../application/useCases/commands/UpdateCollectionUseCase'; import { AuthenticatedRequest } from '../../../../../shared/infrastructure/http/middleware/AuthMiddleware'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export class UpdateCollectionController extends Controller { constructor(private updateCollectionUseCase: UpdateCollectionUseCase) { @@ -34,12 +35,16 @@ export class UpdateCollectionController extends Controller { }); if (result.isErr()) { + // Check if the error is an authentication error + if (result.error instanceof AuthenticationError) { + return this.unauthorized(res, result.error.message); + } return this.fail(res, result.error); } return this.ok(res, result.value); } catch (error: any) { - return this.fail(res, error); + return this.handleError(res, error); } } } diff --git a/src/modules/cards/infrastructure/http/controllers/UpdateNoteCardController.ts b/src/modules/cards/infrastructure/http/controllers/UpdateNoteCardController.ts index 49b5aad6..acd6841e 100644 --- a/src/modules/cards/infrastructure/http/controllers/UpdateNoteCardController.ts +++ b/src/modules/cards/infrastructure/http/controllers/UpdateNoteCardController.ts @@ -2,6 +2,7 @@ import { Controller } from '../../../../../shared/infrastructure/http/Controller import { Response } from 'express'; import { UpdateNoteCardUseCase } from '../../../application/useCases/commands/UpdateNoteCardUseCase'; import { AuthenticatedRequest } from '../../../../../shared/infrastructure/http/middleware/AuthMiddleware'; +import { AuthenticationError } from '../../../../../shared/core/AuthenticationError'; export class UpdateNoteCardController extends Controller { constructor(private updateNoteCardUseCase: UpdateNoteCardUseCase) { @@ -33,12 +34,16 @@ export class UpdateNoteCardController extends Controller { }); if (result.isErr()) { + // Check if the error is an authentication error + if (result.error instanceof AuthenticationError) { + return this.unauthorized(res, result.error.message); + } return this.fail(res, result.error); } return this.ok(res, result.value); } catch (error: any) { - return this.fail(res, error); + return this.handleError(res, error); } } } -- 2.51.2