Tuesday, 13 April 2021

Error making HTTP POST with File in request body

I upgraded from Cypress 6.8.0 to 7.0.1. After the upgrade, when this function is called by one of the Cypress tests

async saveTask (task, file) {
  const requestBody = new FormData()
  requestBody.append('file', file)

  return await http.post('/api/endpoint', requestBody, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
},

I get the following error

TypeError [ERR_INVALID_ARG_TYPE] [ERR_INVALID_ARG_TYPE]: 
The first argument must be of type string or an instance of Buffer or Uint8Array. Received type number (45)
    at write_ (_http_outgoing.js:696:11)
    at ClientRequest.write (_http_outgoing.js:661:15)
    at Request.write (/Users/donal/Library/Caches/Cypress/7.0.1/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/request/request.js:1496:27)
    at /Users/donal/Library/Caches/Cypress/7.0.1/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/request/request.js:546:20
    at Array.forEach (<anonymous>:null:null)
    at end (/Users/donal/Library/Caches/Cypress/7.0.1/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/request/request.js:545:23)
    at Immediate._onImmediate (/Users/donal/Library/Caches/Cypress/7.0.1/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/request/request.js:578:7)
    at processImmediate (internal/timers.js:461:21)
 {
  code: 'ERR_INVALID_ARG_TYPE'
}

The http object that I use to make the POST request is an Axios instance and the file object that I append to the request body is a File. The file object is the cause of the problem, because if I don't append it to the request body, the error doesn't occur.

The error only occurs when the function is run by a Cypress test. Cypress uses Node.js, and judging by the error message above it seems the File type is not allowed. Furthermore, the Axios request config docs indicate that when Axios runs under Node, a File is not allowed.

  // `data` is the data to be sent as the request body
  // Only applicable for request methods 'PUT', 'POST', 'DELETE , and 'PATCH'
  // When no `transformRequest` is set, must be of one of the following types:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - Browser only: FormData, File, Blob
  // - Node only: Stream, Buffer
  data: {
    firstName: 'Fred'
  },

So I guess I need to convert the File objects to something else, so that this function will work both within the app itself, and when run by Cypress.

On the server-side (a Spring Boot app), this file is bound to a MultipartFile

public void handlePost(
    RequestPart(value = "file") MultipartFile file) {

    // controller action body       
}

If my theory that the File type is the problem, what should I use instead and how should I do the conversion?



from Error making HTTP POST with File in request body

No comments:

Post a Comment