From 07d51c3b2609382b41a14db339b12309e8b60d00 Mon Sep 17 00:00:00 2001 From: andrea rota Date: Wed, 26 Jul 2023 11:53:09 +0200 Subject: [PATCH] move error handling to mapAclDomainToHttpError() --- .../geo-feature-tags.service.ts | 1 - .../geo-features/geo-features.controller.ts | 20 +++++-------------- api/apps/api/src/utils/acl.utils.ts | 15 +++++++++++++- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/api/apps/api/src/modules/geo-feature-tags/geo-feature-tags.service.ts b/api/apps/api/src/modules/geo-feature-tags/geo-feature-tags.service.ts index 5f41b0d294..f7c9c17dae 100644 --- a/api/apps/api/src/modules/geo-feature-tags/geo-feature-tags.service.ts +++ b/api/apps/api/src/modules/geo-feature-tags/geo-feature-tags.service.ts @@ -13,7 +13,6 @@ import { } from '@marxan-api/modules/projects/projects.service'; import { UpdateProjectTagDTO } from '@marxan-api/modules/projects/dto/update-project-tag.dto'; -export const featureNotFound = Symbol('feature not found'); export const featureNotFoundWithinProject = Symbol( 'feature not found within project', ); diff --git a/api/apps/api/src/modules/geo-features/geo-features.controller.ts b/api/apps/api/src/modules/geo-features/geo-features.controller.ts index 610aa5ed4a..e02eaf91a2 100644 --- a/api/apps/api/src/modules/geo-features/geo-features.controller.ts +++ b/api/apps/api/src/modules/geo-features/geo-features.controller.ts @@ -45,6 +45,7 @@ import { inlineJobTag } from '@marxan-api/dto/inline-job-tag'; import { RequestWithAuthenticatedUser } from '@marxan-api/app.controller'; import { UpdateFeatureNameDto } from './dto/update-feature-name.dto'; import { isLeft } from 'fp-ts/Either'; +import { mapAclDomainToHttpError } from '@marxan-api/utils/acl.utils'; @IsMissingAclImplementation() @UseGuards(JwtAuthGuard) @@ -100,21 +101,10 @@ export class GeoFeaturesController { ); if (isLeft(result)) { - switch (result.left) { - case featureNotFound: - throw new NotFoundException(`Feature with id ${featureId} not found`); - case featureNotEditable: - throw new ForbiddenException( - `Feature with id ${featureId} is not editable`, - ); - case featureNameAlreadyInUse: - throw new ForbiddenException( - `Feature with id ${featureId} cannot be updated: name is already in use (${body.featureClassName})`, - ); - default: - const _exhaustiveCheck: never = result.left; - throw _exhaustiveCheck; - } + throw mapAclDomainToHttpError(result.left, { + featureId, + featureClassName: body.featureClassName, + }); } else { return this.geoFeatureService.serialize(result.right); } diff --git a/api/apps/api/src/utils/acl.utils.ts b/api/apps/api/src/utils/acl.utils.ts index 3d45c1749d..dbb3c527a5 100644 --- a/api/apps/api/src/utils/acl.utils.ts +++ b/api/apps/api/src/utils/acl.utils.ts @@ -83,6 +83,9 @@ import { } from '@marxan-api/modules/access-control/access-control.types'; import { featureDataCannotBeUploadedWithCsv, + featureNameAlreadyInUse, + featureNotEditable, + featureNotFound, importedFeatureNameAlreadyExist, missingPuidColumnInFeatureAmountCsvUpload, unknownPuidsInFeatureAmountCsvUpload, @@ -94,7 +97,6 @@ import { } from '@marxan-api/modules/geo-features/import/csv.parser'; import { featureNotEditableByUserWithinProject, - featureNotFound, featureNotFoundWithinProject, tagNotFoundForProject, } from '@marxan-api/modules/geo-feature-tags/geo-feature-tags.service'; @@ -108,6 +110,7 @@ interface ErrorHandlerOptions { scenarioId?: string; userId?: string; exportId?: string; + featureClassName?: string; } export const mapAclDomainToHttpError = ( @@ -155,9 +158,11 @@ export const mapAclDomainToHttpError = ( | typeof projectNotFoundForExport | typeof projectIsNotPublished | typeof deleteScenarioFailed + | typeof featureNameAlreadyInUse | typeof featureNotFound | typeof featureNotFoundWithinProject | typeof featureNotEditableByUserWithinProject + | typeof featureNotEditable | typeof projectNotFound | typeof projectNotEditable | typeof projectNotVisible @@ -319,6 +324,10 @@ export const mapAclDomainToHttpError = ( return new BadRequestException( `Scenario ${options?.scenarioId} and associated resources could not be deleted.`, ); + case featureNameAlreadyInUse: + throw new ForbiddenException( + `Feature with id ${options?.featureId} cannot be updated: name is already in use (${options?.featureClassName})`, + ); case featureNotFound: throw new NotFoundException( `Feature with id ${options?.featureId} not found`, @@ -331,6 +340,10 @@ export const mapAclDomainToHttpError = ( throw new ForbiddenException( `Feature with id ${options?.featureId} is not editable by user ${options?.userId} within Project with id ${options?.projectId}`, ); + case featureNotEditable: + throw new ForbiddenException( + `Feature with id ${options?.featureId} is not editable`, + ); case projectNotEditable: throw new ForbiddenException( `Project with id ${options?.projectId} is not editable by user ${options?.userId}`,