snakeeyes08
snakeeyes08

Reputation: 55

Node JS Express how can I send a 404 error if a bad request is made to third party API?

In my Node JS server I have this route handler that sends a request to a third party API to get a username:

app.get('/players/:player', apiLimiter, function(request, response) {

const player = request.params.player;
const api_url = `https://api.com/shards/steam/players?filter[playerNames]=${player}`;

var options = {
   method: "GET",
   observe: 'body',     
   };

   let apiRequest = https.request(api_url, options, function (res) {

    let data = "";

    res.on("data", chunk => {
        data += chunk;
    }) 

    res.on("end", () => { 

           let objectParsed =  JSON.parse(JSON.stringify(data)); 
           response.send(objectParsed);               
    }) 

  if(!player) {
  res.status(404).send("Not found.");
}


})
apiRequest.end();

}) 

This works fine to get a user that exists. However, if I put in a fake username to my /players page, that page still loads with a 200 status instead of getting a 404 response. The page loads and looks broken because it's not actually getting any data from the API.

I feel like this is a dumb question .. In my research I have found how to handle errors if it's just the route, and not if it's the route dependent on the path parameter as in /players/:player

I found a question that was similar to mine (How to throw a 404 error in express.js?) and I tried using an If statement: if (!player){res.status(404).send("Not found."); } but no dice. Am I using this if statement in the wrong place?

How can I get my Node JS server to respond with a 404 if the user from the database doesn't exist?

Upvotes: 1

Views: 3411

Answers (1)

jfriend00
jfriend00

Reputation: 707456

You have to check the result of the API call and see if you got valid data back and send the 404 there. I also added a check to make sure something was passed for the player name and send back a 400 (bad request) if there's no player specified at all:

app.get('/players/:player', apiLimiter, function(request, response) {

    const player = request.params.player;
    if (!player) {
        res.status(400).send("No player specified.");
        return;
    }

    const api_url = `https://api.com/shards/steam/players?filter[playerNames]=${player}`;

    var options = {
        method: "GET",
        observe: 'body',
    };

    let apiRequest = https.request(api_url, options, function(res) {

        let data = "";

        res.on("data", chunk => {
            data += chunk;
        })

        res.on("end", () => {

            let objectParsed = JSON.parse(data);
            // test objectParsed here
            if (!some condition in objectParsed) {
                res.status(404).send("No data for that player name.");
            } else {
                response.send(objectParsed);
            }
        });
    });
    apiRequest.end();
});

Also, you don't want JSON.parse(JSON.stringify(data)) here. Your data is already a string. Just do JSON.parse(data).

FYI, if you use a small http request library such as got(), this code gets a lot simpler as it accumulates the response and parses the JSON for you in one line of code as in:

let data = await got(options).json()

Upvotes: 1

Related Questions