27

I want to be able to use my React app to make a GET request to my server, which is suppose to prompt my server to make an GET request to an external API. I'm using axios and tried using request but both are giving me ERRTIMEOUT. The request are definitely working as I've tried on my frontend application and the requests work

const express = require("express");
const axios = require("axios");
const router = express.Router();

router.get("/test", (req, res, next) => {
    console.log("'/test' call");
    axios.get("https://api.neoscan.io/api/main_net/v1/get_all_nodes")
       .then(data => res.json(data))
       .catch(err => res.secn(err));
})

module.exports = router;`

The error code

GGWP! { Error: connect ETIMEDOUT 104.25.167.105:443
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1113:14)
  errno: 'ETIMEDOUT',
  code: 'ETIMEDOUT',
  syscall: 'connect',
  address: '104.25.167.105',
  port: 443,
  config:
   { adapter: [Function: httpAdapter],
     transformRequest: { '0': [Function: transformRequest] },
     transformResponse: { '0': [Function: transformResponse] },
     timeout: 0,
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     headers:
      { Accept: 'application/json, text/plain, */*',
        'User-Agent': 'axios/0.18.0' },
     method: 'get',
     url: 'https://api.neoscan.io/api/main_net/v1/get_all_nodes',
     data: undefined },
  request:
   Writable {
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: true,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        emitClose: true,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     _events:
      { response: [Function: handleResponse],
        error: [Function: handleRequestError] },
     _eventsCount: 2,
     _maxListeners: undefined,
     _options:
      { protocol: 'https:',
        maxRedirects: 21,
        maxBodyLength: 10485760,
        path: '/api/main_net/v1/get_all_nodes',
        method: 'get',
        headers: [Object],
        agent: undefined,
        auth: undefined,
        hostname: 'api.neoscan.io',
        port: null,
        nativeProtocols: [Object],
        pathname: '/api/main_net/v1/get_all_nodes' },
     _redirectCount: 0,
     _redirects: [],
     _requestBodyLength: 0,
     _requestBodyBuffers: [],
     _onNativeResponse: [Function],
     _currentRequest:
      ClientRequest {
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [TLSSocket],
        connection: [TLSSocket],
        _header:
         'GET /api/main_net/v1/get_all_nodes HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nUser-Agent: axios/0.18.0\r\nHost: api.neoscan.io\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path: '/api/main_net/v1/get_all_nodes',
        _ended: false,
        res: null,
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        _redirectable: [Circular],
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     _currentUrl: 'https://api.neoscan.io/api/main_net/v1/get_all_nodes' },
  response: undefined }

Here's the additional error code that I'm getting after responding

(node:35220) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at stringify (.\new-viewer\node_modules\express\lib\response.js:1119:12)
    at ServerResponse.json (.\new-viewer\node_modules\express\lib\response.js:260:14)
    at ServerResponse.send (.\new-viewer\node_modules\express\lib\response.js:158:21)
    at axios.get.then.catch.err (.\new-viewer\server\api\index.js:45:27)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:40496) UnhandledPromiseRejectionWarning: TypeError: res.error is not a function
    at axios.get.then.catch.err (.r\server\api\index.js:36:17)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:40496) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:40496) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
mLjH
  • 425
  • 2
  • 7
  • 11

5 Answers5

18

Axios returns you the whole response, so if you try to send this you get a circular dependecy error. So on .then(data => res.json(data)), data is actually the response.

Try .then(response => res.json(response.data))

Alex G
  • 1,897
  • 2
  • 10
  • 15
7
  1. You don't have to enclose your axios call in a try...catch as axios already has a catch block.

  2. Your express handler has to send a response back when axios gets a response from the API call or axios catches an error during the API call.

Your code should look something like this

router.get("/test", (req, res, next) => {
  console.log("'/test' call");
  axios.get("https://api.neoscan.io/api/main_net/v1/get_all_nodes")
    .then(data => res.json(data))
    .catch(err => next(err));
})

If you fancy async...await, you can write your code like this

router.get("/test", async (req, res, next) => {
  console.log("'/test' call");
  try {
    const res = await axios.get("https://api.neoscan.io/api/main_net/v1/get_all_nodes");
    res.json(data);
  }
  catch (err) {
    next(err)
  }
})
Dinesh Pandiyan
  • 5,814
  • 2
  • 30
  • 49
  • @c-chavez Why should we await `res.json(data)`? – Dinesh Pandiyan Dec 19 '18 at 08:20
  • hi @DineshPandiyan i've tired your 1st method and i'm still getting errors. i've updated the initial post with the errors at the bottom. they are all UnhandledPromiseRejectionWarnings. And I'm still not able to get the request – mLjH Dec 19 '18 at 08:35
  • @mLjH I have updated my answer. Looks like you are getting are response from the axios call but converting it to json is where the problem is. Try sending the error to `next(err)` callback and see what's happening. – Dinesh Pandiyan Dec 19 '18 at 08:54
  • It returns me `Error: connect ETIMEDOUT 104.25.168.105:443 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1113:14)` – mLjH Dec 19 '18 at 09:03
  • It's almost like your firewall is blocking the address. I am able to hit the URL from my place and get the response. – Dinesh Pandiyan Dec 19 '18 at 09:10
  • hey @DineshPandiyan i forget to mention that if I make this call in my client (frontend React), the ruquest goes through. But when I make this via my server (backend Express), the request will Timeout. So I take my words back, my company shouldn't have blocked it given that my React app is able to get a request fro mit – mLjH Dec 19 '18 at 09:20
5
const express = require('express')
const axios = require('axios')
const app = express()

app.get("/", async (req, res) => {
    try {
        const response = await axios.get("https://jsonplaceholder.typicode.com/posts")
        res.json(response.data)
    }
    catch (err) {
        console.log(err)
    }
})

app.get('*', (req, res) => {
    res.status(500).json({ message: "error" })
})

app.listen(3001)
Manoj M
  • 189
  • 2
  • 4
  • 1
    Please provide additional details in your answer. As it's currently written, it's hard to understand your solution. – Community Sep 01 '21 at 06:40
4

You forgot to respond to the client:

 try{
    axios.get("https://api.neoscan.io/api/main_net/v1/get_all_nodes")
           .then(data => res.status(200).send(data))
           .catch(err => res.send(err));
 }
 catch(err){
    console.error("GG", err);
 }
abdulbarik
  • 6,101
  • 5
  • 38
  • 59
  • I've tried this but am still getting the same errors. Except now, it's also telling me other stuff like `UnhandledPromiseRejectiongWarning: TypeError: Converting circular structure to JSON`, `UnhandledPromiseRejectiongWarning: Unhandled promise rejection.`... not handled with .catch() – mLjH Dec 19 '18 at 08:13
  • Just check your catch block, you are getting other error. – abdulbarik Dec 19 '18 at 08:15
1
            Modifying the previous answer ,
            try using response.data , then send it back to handler will solve the issue 
            try the snippet below
            const express = require('express');
            const axios=require("axios");
            const { response } = require('express')
            const router = express.Router();

            router.get("/",async (req, res, next) => {
            
            try {
                const response = await axios.get("https://api.neoscan.io/api/main_net/v1/get_all_nodes");
                console.log(response.data);
                res.send(response.data);
            }
            catch (err) {
                next(err)
            }
            })


            module.exports=router;
kumar31rajesh
  • 71
  • 1
  • 9