简体   繁体   中英

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."); } 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?

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM