Skip to content

FilesAPI.files.upload() w/fileContent parameter fails #719

@Lokaltog

Description

@Lokaltog

This error has caused us some grief today. File uploading works fine when only passing the fileInfo parameter and using the return URL and upload in two steps. But when uploading a file with the file contents as the second parameter the call will fail because the HTTP client attempts to decode an empty response as JSON:

FetchError: invalid json response body at https://westeurope-1.cognitedata.com/api/v1/files/storage/cognite/2550729626496599/2650922202326675/Test%20ignore%20CDF%20errors?sig=CIJaPwzhsswMFCEzK1Hzq6uay3UvnqjqQ251VGmnV9k%3D&se=2021-11-24T21%3A12%3A47Z&sv=2019-02-02&rsct=application%2Foctet-stream&sp=cw&sr=b reason: Unexpected end of JSON input
    at /home/kim/.cache/bazel/_bazel_kim/f9e06cc95dcfae12159e051cadf89bca/execroot/frontend_app_server/bazel-out/k8-fastbuild/bin/services/simconfig-api/simconfig-api.binary.sh.runfiles/npm/node_modules/node-fetch/lib/index.js:272:32

This can be traced back to the following code:

private static getResponseHandler<ResponseType>(
responseType?: HttpResponseType
): ResponseHandler<ResponseType> {
switch (responseType) {
case HttpResponseType.ArrayBuffer:
return BasicHttpClient.arrayBufferResponseHandler;
case HttpResponseType.Text:
return BasicHttpClient.textResponseHandler;
default:
return BasicHttpClient.jsonResponseHandler;
}
}

The upload call referred to in the stack trace above fails because responseType is undefined in the lookup above. This causes the HTTP client to attempt to decode the response from the upload endpoint as JSON, but the upload endpoint returns 201 and an empty body. The JSON decoding then fails because an empty string isn't valid JSON.

The end result is that the file is uploaded to CDF, but it also throws a confusing error message that's difficult to track down, and waitUntilAcknowledgement is ignored and any logic after the actual file upload doesn't work because an exception is thrown when decoding invalid JSON.

A suggestion to resolve this issue is to not use JSON decoding as a fallback, because this will fail for any invalid JSON object (including empty strings). A more appropriate fallback decoder would probably be plain text.

Alternatively this could be wrapped in a try/catch with an appropriate fallback for failed JSON decoding, maybe also supplemented with some sanity checks, i.e. not attempting to JSON decode empty strings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions