'Axios POST request fails with error status code 500: Internal Server error

I'm trying to send a POST request locally with a username and password in the body through Axios.

I'm deploying a Flask app on http://127.0.0.1:5000/login, which handles the /login route. The POST request fails with the following error

POST http://127.0.0.1:5000/login 500 (INTERNAL SERVER ERROR)
Error: Request failed with status code 500
    at createError (createError.js:16)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

I researched a bit and thought it might be a problem with CORS, but this doesn't seem to be the case because I tried an Axios GET request and it worked fine (response logged properly). Here's part of my code

axios.get("http://127.0.0.1:5000").then(function(response) {
        console.log(response);
      }).catch(function(error) {
        console.log(error);
      })
axios.post("http://127.0.0.1:5000/login", {
        username: this.state.username,
        password: this.state.password
      }).then(function(response) {
        console.log(response);
      }).catch(function(error) {
        console.log(error);
      })

Looking at Chrome DevTools, I can see that the POST request payload is properly populated. I then tried printing out the keys server-side in the Flask app using the following code, but I got nothing, empty. (which was expected since the POST request failed)

dict = request.form
    for key in dict:
        print('form key '+dict[key])

HOWEVER using Postman with the corresponding keys and values works properly and returns a response and prints out the keys (see above). Where is the failure coming from? Why would the POST request fail when a GET seems to work just fine?



Solution 1:[1]

Feb 2021. Wasted 2 hours on this. Not much help on this famous library on internet.

Solution:

  • In the catch block, the error which will always be 500 internal server error
  • so, use error.response.data instead of error.

Code:

try {
  let result = await axios.post(          // any call like get
    "http://localhost:3001/user",         // your URL
    {                                     // data if post, put
      some: "data",
    }
  );
  console.log(result.response.data);
} catch (error) {
  console.error(error.response.data);     // NOTE - use "error.response.data` (not "error")
}

Update:

I ended up writing a common function for handing error:

File: common.app.js

export const errorUtils = {
  getError: (error) => {
    let e = error;
    if (error.response) {
      e = error.response.data;                   // data, status, headers
      if (error.response.data && error.response.data.error) {
        e = error.response.data.error;           // my app specific keys override
      }
    } else if (error.message) {
      e = error.message;
    } else {
      e = "Unknown error occured";
    }
    return e;
  },
};

More info: https://github.com/axios/axios#handling-errors

Solution 2:[2]

So I also got stuck in the same problem and the solution that I found was something like this :

let data = JSON.stringify({
  username: this.state.username,
  password: password
});

const response = axios.post(url,data,{headers:{"Content-Type" : "application/json"}});

This solution worked for me.

Solution 3:[3]

Apparently Axios didn't take kindly to the raw JSON object

{username: this.state.username, password: password} 

but passing the data into a FormData object seemed to work just fine!

Solution 4:[4]

After working 2 hours, I realized I made a mistake about the body and data. So, in the axios make sure you pass the data like this.

async function loadToken(){
  try{
    response = await axios({
      url: ``, 
      headers: {
        'Authorization': '',
        'Content-Type': '',
      },
      data: '',
      method: 'POST'
    });
    let data = response.data;
    return {
      tokenInfo:data,
      timestamp:new Date().getTime()
    }
  } catch(err) {
    console.log("err->", err.response.data)
    return res.status(500).send({ret_code: ReturnCodes.SOMETHING_WENT_WRONG});
  } 
}

My previous code pass the data like this, which is wrong

async function refreshToken(){
  try{
      let headers = {
        authorization: '',
        'Content-Type': ''
      }
      let url =  ``
      let body = {
        grant_type: '',
        refresh_token: global.tokenInfo.refresh_token
      }
      data = await axios.post(url, body, {headers});
      let data = response.data
      console.log(data)
      return {
        tokenInfo:data,
        timestamp:new Date().getTime()
      }
  } catch(err) {
      console.log("err->", err.response)
      return res.status(500).send({ret_code: ReturnCodes.SOMETHING_WENT_WRONG});
  }
}

Simply try my first code, hope that solves your issue.

Solution 5:[5]

Most of the time it happens because of using wrong content type header.

Open postman and see "Body" tab. There you can find the content type of your post data. It's also accessible from "Headers" tab. There should be a Content-Type header. The correct format of data you send through a POST request depends on Content-Type header. for example, json content type requires a json (javascript object) data or form-data content type requires a FormData.

To set a header in axios, change the code like this:

axios.post("http://127.0.0.1:5000/login", {
        username: this.state.username,
        password: this.state.password
      }, {
        headers: {'Content-Type': 'application/json'}
      }).then(function(response) {
        console.log(response);
      }).catch(function(error) {
        console.log(error);
      })

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Aman Singh
Solution 3 M Xiao
Solution 4 isFibonacci
Solution 5 Parsa Enami