Upload application file resolver exception management and integration coverage (#20803)

# Introduction
Earlier and better exception handling of the upload application file
resolver
+ coverage
This commit is contained in:
Paul Rastoin
2026-05-21 14:45:54 +02:00
committed by GitHub
parent 4b8c722b41
commit 570c57563a
6 changed files with 402 additions and 3 deletions
@@ -22,9 +22,9 @@ import { UploadApplicationFileInput } from 'src/engine/core-modules/application/
import { WorkspaceMigrationDTO } from 'src/engine/core-modules/application/application-development/dtos/workspace-migration.dto';
import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter';
import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service';
import { resolveManifestAssetUrls } from 'src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util';
import { ApplicationTokenPairDTO } from 'src/engine/core-modules/application/application-oauth/dtos/application-token-pair.dto';
import { ApplicationRegistrationVariableService } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.service';
import { resolveManifestAssetUrls } from 'src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util';
import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service';
import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum';
import {
@@ -37,14 +37,14 @@ import { FileStorageService } from 'src/engine/core-modules/file-storage/file-st
import { FileDTO } from 'src/engine/core-modules/file/dtos/file.dto';
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service';
import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service';
import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
import { streamToBuffer } from 'src/utils/stream-to-buffer';
@@ -219,6 +219,20 @@ export class ApplicationDevelopmentResolver {
);
}
const application = await this.applicationService.findByUniversalIdentifier(
{
universalIdentifier: applicationUniversalIdentifier,
workspaceId,
},
);
if (!isDefined(application)) {
throw new ApplicationException(
'Application not found in workspace.',
ApplicationExceptionCode.APPLICATION_NOT_FOUND,
);
}
const buffer = await streamToBuffer(createReadStream());
return await this.fileStorageService.writeFile({
@@ -1,15 +1,21 @@
import { ArgsType, Field } from '@nestjs/graphql';
import { IsNotEmpty } from 'class-validator';
import { FileFolder } from 'twenty-shared/types';
import { IsSafeRelativePath } from 'src/engine/core-modules/file-storage/validators/is-safe-relative-path.validator';
@ArgsType()
export class UploadApplicationFileInput {
@Field(() => String)
@IsNotEmpty()
applicationUniversalIdentifier: string;
@Field(() => FileFolder)
fileFolder: FileFolder;
@Field(() => String)
@IsNotEmpty()
@IsSafeRelativePath()
filePath: string;
}