Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't upload files from AWS S3 #612

Open
arampetrosyann opened this issue Nov 7, 2022 · 10 comments
Open

Can't upload files from AWS S3 #612

arampetrosyann opened this issue Nov 7, 2022 · 10 comments

Comments

@arampetrosyann
Copy link

let localVarRequestOptions: localVarRequest.Options = {

I'm getting an error when trying to upload a file. (Files API)

The error is - { type: 'Validation', title: 'Validation failure', detail: 'No file is was attached' }

Request body is missing in request options.

@RettBehrens
Copy link
Contributor

Hi @arampetrosyann I'm unable to replicate your error using our sample app.

Code snippet:

const filename = "xero-dev.png";
const pathToUpload = path.resolve(__dirname, "../public/images/xero-dev.png");
const readStream = fs.createReadStream(pathToUpload);
const contentType = mime.lookup(filename);

const uploadFile = await xero.filesApi.uploadFile(req.session.activeTenant.tenantId, readStream, filename, contentType);

Response body:

{ "name": "xero-dev.png", "mimeType": "image/png", "size": 34843, "createdDateUtc": "2022-11-07T21:53:13.8370000", "updatedDateUtc": "2022-11-07T21:53:13.8370000", "user": { "id": "96536500-45b9-4170-b4ad-40c180fb9f48", "name": "[email protected]", "firstName": "Rett", "lastName": "Behrens", "fullName": "Rett Behrens" }, "id": "a38238cf-d108-416b-8206-89655c7a8b2b", "folderId": "f8405741-5cbb-405f-9343-2cc221004843" }

File in Xero UI:
Screen Shot 2022-11-07 at 15 01 48

Can you please provide more information?

  • What version of Xero-Node SDK are you using?
  • Can you include a code snippet?

@arampetrosyann
Copy link
Author

Hi @RettBehrens

Code:

    const fileStream = s3
      .getObject({
        Bucket: file.bucket,
        Key: file.externalKey,
      })
      .createReadStream()

    const [fileName, mimeType] = this.constructor.processFileName(fileExp.name)

    const res = await this.filesApi.uploadFile(
      this.tenantId,
      fileStream,
      fileName,
      fileName,
      mimeType
    ) 

I'm using AWS S3.

Version of SDK - 4.21.0

@RettBehrens
Copy link
Contributor

Is there any additional indication of where this error is originating?
{ type: 'Validation', title: 'Validation failure', detail: 'No file is was attached' }

When testing in the sample app, the SDK error if no body present is Error: Required parameter body was null or undefined when calling uploadFile.

Can you provide your app Client ID so I can check the logs on our side?

@RettBehrens
Copy link
Contributor

@arampetrosyann checking in to see if you've resolved the issue on your end or if this remains ongoing?

@arampetrosyann
Copy link
Author

@RettBehrens no I couldn't resolve that. The error comes from response.

Client ID - A2F4E2DB397C4107B2671C1FB4B14F27
Correlation ID - bcfa76c7-5774-4daf-8536-458d755e9e3d

@arampetrosyann arampetrosyann changed the title Add request body in request options Can't upload files from AWS S3 Nov 17, 2022
@RettBehrens
Copy link
Contributor

Your request resulting in 400:

----------------------------998237666144744215888171
Content-Disposition: form-data; name="name"

bairds-sandpiper-gff0f83b00_1280.jpg
----------------------------998237666144744215888171
Content-Disposition: form-data; name="filename"

bairds-sandpiper-gff0f83b00_1280.jpg
----------------------------998237666144744215888171
Content-Disposition: form-data; name="mimeType"

image/jpeg
----------------------------998237666144744215888171
Content-Disposition: form-data; name="bairds-sandpiper-gff0f83b00_1280.jpg"
Content-Type: application/octet-stream

My request resulting in 201:

----------------------------459349396614277166041519
Content-Disposition: form-data; name="name"

xero-dev.png
----------------------------459349396614277166041519
Content-Disposition: form-data; name="filename"

xero-dev.png
----------------------------459349396614277166041519
Content-Disposition: form-data; name="mimeType"

image/png
----------------------------459349396614277166041519
Content-Disposition: form-data; name="xero-dev.png"; filename="xero-dev.png"
Content-Type: image/png

I see that your Content-Type does not match your mimeType, where mine does. Can you try overriding the value with the correct type and send the request again?

Allowed file types:

BMP NUMBERS RTF
CSV ODF RTF/TEXT
DOC ODS TIF
DOCX ODT TIFF
EML PAGES TXT
GIF PDF XLS
JPEG PNG XLSX
JPG PPT ZIP
KEYNOTE PPTX 7Z
MSG RAR  

@arampetrosyann
Copy link
Author

    const [fileName, mimeType] = this.constructor.processFileName(fileExp.name)

    const res = await this.filesApi.uploadFile(
      this.tenantId,
      fileStream,
      fileName,
      fileName,
      mimeType,
      { headers: { 'Content-Type': mimeType } }
    ) 

Result is the same.

Correlation ID - e02361e0-b055-47ea-ac38-166f50b132e2

@RettBehrens
Copy link
Contributor

The request header content type is correct, however, the request body is still showing application/octet-stream. Reading the docs it seems S3 will default to application/octet-stream if you don't specify content type when uploading. It seems you can also specify content type when calling getObject Can you try this?

const fileStream = s3
      .getObject({
        Bucket: file.bucket,
        Key: file.externalKey,
        ResponseContentType: 'image/jpeg',
      })
      .createReadStream()

If the above works, can you specify content type when uploading to S3?

@arampetrosyann
Copy link
Author

That was inefficient.

Correlation ID - 61c63e0d-f8ce-4a15-8595-a4b91f107549

I always recieve the same error message.

Can I send a file with base64 format?

@RettBehrens
Copy link
Contributor

Hi @arampetrosyann

From the dev team:

I tried uploading a file with Content-Type set to application/octet-stream as seen in the attached screen capture. The API seems to resolve to the actual content-type of the file attached (if the file exists).. The only instance I see this 400 error is if there is no file attached with the request. Do you know if the user has validated that they've retrieved the file from S3 successfully?

files-api-uploading-a-file

Additionally:

The other difference in the two requests you posted here, is that yours has a name and a filename whereas his request only has name could that be messing with it?

Based on the dev team feedback, I have a couple questions:

  • Can you confirm you're successfully retrieving the file from S3?
  • Can you console.log the output for const [fileName, mimeType] = this.constructor.processFileName(fileExp.name)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants