Not being able to read statusCode when sending a request

46 Views Asked by At

I am developing an api with node.js but i am having trouble with one of my routers while sending a request in postman.

The following is my router:

    //@route   GET api/profile/github/:username
    //@desc    Get user repos from github
    //@access  public

    router.get('/github/:username', (req,res)=>{
        try {
            const options = {
                uri: `https://api/github.com/users/${req.params.username}/repos?per_page=5&sort=created:asc&client_id=${config.get('githubClientId')}&client_secret=${config.get('githubSecret')}`,
                method:'GET',
                headers:{'user_agent': 'node.js'}

            };

            request(options, (error, response, body) => {
                if(error) console.error(error);

                if(response.statusCode !== 200){
                    res.status(404).json('No Github profile found');
                }

                res.json(JSON.parse(body));
            });

        } catch (error) {

            console.error(error.message);
            res.status(500).send('Server Error');
        }
    })

So in this route i am trying to find a github username that is being passed via the uri.

This is the request i am sending:

http://localhost:5000/api/profile/github/<GITHUB_USERNAME>

but when i send my request i get the following error in my VSC console.

Cannot read properties of undefined (reading 'statusCode')

if(response.statusCode !==200){
1

There are 1 best solutions below

0
jfriend00 On

There are a couple issues here:

First, https://api/github.com/users/xxx should be https://api.github.com/users/xxx. You put a / where there should have been a . .

And, in fact, your very code should be showing the error:

Error: getaddrinfo ENOTFOUND api
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:71:26) {
  errno: -3008,
  code: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'api'
}

which is telling you that the domain api was not found. It's looking for that domain because of the error in your URL.

Second, this error is complicated in your code because if you get an error returned from the request() library, then the callback arguments response and body are invalid, but you try to use them. The physical request did not succeed so there is no response or body.

You can amend your code like this:

router.get('/github/:username', (req, res) => {
    try {
        const options = {
            uri: `https://api/github.com/users/${req.params.username}/repos?per_page=5&sort=created:asc&client_id=${config.get('githubClientId')}&client_secret=${config.get('githubSecret')}`,
            method: 'GET',
            headers: { 'user_agent': 'node.js' }

        };

        request(options, (error, response, body) => {
            if (error) {
                console.error(error);
                res.status(500).json({code: error.code, message: "Network error communicating with github"});
                return;
            }

            if (response.statusCode !== 200) {
                res.status(404).json('No Github profile found');
                return;
            }

            res.json(JSON.parse(body));
        });

    } catch (error) {

        console.error(error.message);
        res.status(500).send('Server Error');
    }
});

This handles the error by returning a 500 status and creating an error object to send back to the client. It also adds return statements after sending a response so the following code doesn't execute and try to send other responses.


NOTE: The request() library has been deprecated since early 2020 and will no longer be developed with new features. It is NOT recommended for new code. You can use newer, promise-based libraries such as node-fetch, got or any of the others listed here. In the most recent versions of nodejs, you can use the built-in version of fetch.