lukeautry / tsoa

Build OpenAPI-compliant REST APIs using TypeScript and Node
MIT License
3.33k stars 481 forks source link

Can't Handle Optional File Field on multipart/form-data #1585

Closed shibukazu closed 4 months ago

shibukazu commented 4 months ago

Sorting

Expected Behavior

The following code is an example of a post endpoint handler:

public async postHandler(
  @FormField("userId") userId: string,
  @UploadedFile("file1") file?: Express.Multer.File,
  ): Promise<Response> {}

The expected behavior is that this handler can handle multipart/form-data requests correctly when only userId is included in the request.

Current Behavior

Currently, it outputs an error message like the following:

{
    "message": "Cannot read properties of undefined (reading 'length')"
}

Possible Solution

This issue seems to be caused by an incorrect implementation of the template engine, specifically expressTemplateService.ts line 89. When the file field is optional in @UploadedFile and not included in the actual request, fileArgs becomes undefined. The current implementation does not account for this and tries to call the length property, resulting in the aforementioned error. To address this issue, the implementation should be modified as follows:

case 'formData': {
    const files = Object.values(args).filter(param => param.dataType === 'file');
    if (param.dataType === 'file' && files.length > 0) {
        const requestFiles = request.files;
        const fileArgs = this.validationService.ValidateParam(param, requestFiles[name], name, fieldErrors, undefined, this.minimalSwaggerConfig);
        return fileArgs ? (fileArgs.length === 1 ? fileArgs[0] : fileArgs) : undefined;
    }
    else if (param.dataType === 'array' && param.array && param.array.dataType === 'file') {
        return this.validationService.ValidateParam(param, request.files, name, fieldErrors, undefined, this.minimalSwaggerConfig);
    }
    return this.validationService.ValidateParam(param, request.body[name], name, fieldErrors, undefined, this.minimalSwaggerConfig);
}

May I publish pull request for this issue?

Context (Environment)

Version of the library: 6.1.4 Version of NodeJS: 18

WoH commented 4 months ago

@jackey8616