So I am trying to get some data from the food-data-central API. In my program I console log the data, but I don't get any results on the console.
The only thing I get is an error about Fetch Error
import fetch from "node-fetch"
const params = {
api_key: <apiKey>,
query: 'chicken breast raw',
dataType: ["Survey (FNDDS)"],
pagesize: 5,
}
const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}`
function getData(){
return fetch(api_url).then(response => response.json())
}
getData().then(data => {
const foods = data.foods[0];
console.log("Protein: ");
console.log(foods.foodNutrients[0].value);
console.log("Fats: ");
console.log(foods.foodNutrients[1].value);
console.log("Carbs: ");
console.log(foods.foodNutrients[2].value);
});
The output that I get:
reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
^
FetchError: request to https://api.nal.usda.gov/fdc/v1/foods/search?api_key=3Bi6rNu3MiTYMaPwMf2u5vs1xAtdKS0n5HoFpgy9&query=chicken%20breast%20raw&dataType=Survey%20(FNDDS)&pageSize=5 failed, reason: connect ETIMEDOUT 2600:1f12:18a:7d00:217:68d:2c2:3718:443
at ClientRequest.<anonymous> (/home/dflorian251/Desktop/node_modules/node-fetch/lib/index.js:1505:11)
at ClientRequest.emit (node:events:513:28)
at TLSSocket.socketErrorListener (node:_http_client:481:9)
at TLSSocket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
type: 'system',
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT'
Is something wrong with the node-fetch module ?
Related
I want to get an object when the HTTP request failed.
something like this
Object = {status: 404, reason: 'Not found', body: '404 Not found'}
I have read How can I get the status code from an HTTP error in Axios?,But It does not work for me.
This is the JS code,
const axios = require('axios');
axios({
url:'https://www.icofont.cn//sd',
method:'GET',
})
.then(response=>{
console.log(response.status);
})
.catch(error=>{
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
})
I always get an undefined of the error.response.So I get an error. I can get an error object. How can I extract 404 Not found from this object?
The problem is that you are assuming the error is returned in the response. It could also be in the request (e.g. while connecting to the server before making the request). I addded console.log(error) and found that on my computer the error is in the request:
AxiosError: connect ECONNREFUSED 38.238.92.52:443
at AxiosError.from (/run/user/1000/test123/node_modules/axios/dist/node/axios.cjs:725:14)
at RedirectableRequest.handleRequestError (/run/user/1000/test123/node_modules/axios/dist/node/axios.cjs:2467:25)
at RedirectableRequest.emit (node:events:513:28)
at eventHandlers.<computed> (/run/user/1000/test123/node_modules/follow-redirects/index.js:14:24)
at ClientRequest.emit (node:events:513:28)
at TLSSocket.socketErrorListener (node:_http_client:494:9)
at TLSSocket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
port: 443,
address: '38.238.92.52',
syscall: 'connect',
code: 'ECONNREFUSED',
errno: -111,
config: {
[...]
},
request: <ref *1> Writable {
[...]
},
cause: Error: connect ECONNREFUSED 38.238.92.52:443
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '38.238.92.52',
port: 443
}
}
/run/user/1000/test123/test.js:11
console.log(error.response.data);
^
TypeError: Cannot read properties of undefined (reading 'data')
at /run/user/1000/test123/test.js:11:32
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.10.0
The server you are connecting to does not seem to support HTTPS. It can only be connected to if https://www.icofont.cn//sd is changed to http://www.icofont.cn//sd, and then the 404 comes out.
Instead of assuming the error is in the response or request, it should be checked for. The official example explains this.
Your fixed example will look like the following:
const axios = require('axios');
axios({
url:'http://www.icofont.cn//sd',
method:'GET',
})
.then(response=>{
console.log(response.status);
})
.catch(error=>{
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
})
I have created an endpoint and when i am sending a request on the endpoint i am receiving the object for the offices but when it comes to the recipient i got an error of SyntaxError: Unexpected token # in JSON at position 0 and when i checked on the project's log from where i am getting the request it gives me an error of StatusCodeError: 400.but when i am sending the request using postman it doesn't give any error it worked fine. here is the code of the endpoint.
const { growthfilemsdb } = require('../config');
const { code } = require('../utils/reportUtils');
const { getBearerToken, tokenValidator } = require('../utils/http');
const update = async (req, res) => {
try {
const bearerToken = getBearerToken({ headers: req.headers })
if (tokenValidator(bearerToken)) {
const officeID = req.body.officeId;
const recipientID = req.body.recipientId;
const data = {
requestBody: req.body,
};
if (
req.body.hasOwnProperty('officeId') &&
req.body.template === 'office'
) {
const officeDb = await growthfilemsdb
.collection('Offices')
.doc(officeID)
.set(data.requestBody, { merge: false });
return res.status(code.ok).send({ success: true, message: `Success` });
} else if (
req.body.hasOwnProperty('recipientId') &&
req.body.hasOwnProperty('officeId') &&
req.body.template === 'recipient'
) {
const recipientData = await growthfilemsdb
.collection('Offices')
.doc(officeID)
.collection('Recipients')
.doc(recipientID)
.set(data.requestBody, { merge: false });
return res.status(code.ok).send({ success: true, message: `Success` });
}
} else {
res.status(code.forbidden).send('Forbidden');
}
} catch (error) {
res
.status(code.internalServerError)
.send({ success: false, message: `Internal Server Error` });
}
};
module.exports = { update };
and i have used this code in the index.js file as in this way
const bodyParser = require('body-parser');
const app = express();
const updateRecord = require('./api/updateApi');
require('dotenv').config();
app
.use(bodyParser.urlencoded({ extended: true }))
app.put('/activity', updateRecord.update);
this is the error i got when i am sending request
StatusCodeError: 400 - "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Bad Request</pre>\n</body>\n</html>\n"
at new StatusCodeError (/srv/node_modules/request-promise-native/node_modules/request-promise-core/lib/errors.js:32:15)
at Request.plumbing.callback (/srv/node_modules/request-promise-native/node_modules/request-promise-core/lib/plumbing.js:104:33)
at Request.RP$callback [as _callback] (/srv/node_modules/request-promise-native/node_modules/request-promise-core/lib/plumbing.js:46:31)
at Request.self.callback (/srv/node_modules/request/request.js:185:22)
at emitTwo (events.js:126:13)
at Request.emit (events.js:214:7)
at Request.<anonymous> (/srv/node_modules/request/request.js:1161:10)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at IncomingMessage.<anonymous> (/srv/node_modules/request/request.js:1083:12)
and this is the error i am getting when i am receiving
SyntaxError: Unexpected token # in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError (/worker/node_modules/body-parser/lib/types/json.js:157:10)
at parse (/worker/node_modules/body-parser/lib/types/json.js:83:15)
at /worker/node_modules/body-parser/lib/read.js:121:18
at invokeCallback (/worker/node_modules/raw-body/index.js:224:16)
at done (/worker/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/worker/node_modules/raw-body/index.js:273:7)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
I'm using firebase realtime database and cloud functions. The goal is on a create event in realtime database to send a message to Discord webhook.
I'm getting a 400 status error and can't work out how to get around it.
Here is my code:
const WEBHOOK_URL = 'MY DISCORD WEBHOOK URL';
exports.webhook = functions.database.ref('{sessionId}').onCreate(async (snap) => {
const sessionData = snap.val();
const response = await request({
uri: WEBHOOK_URL,
method: 'POST',
json: true,
body: sessionData.dateCreated,
resolveWithFullResponse: true,
});
if (response.statusCode >= 400) {
throw new Error(`HTTP Error: ${response.statusCode}`);
}
console.log('SUCCESS! Posted', snap.ref);
And the error message:
Error ->
StatusCodeError: 400 - {"_misc":["Only dictionaries may be used in a DictType"]}
at new StatusCodeError (/srv/node_modules/request-promise-core/lib/errors.js:32:15)
at Request.plumbing.callback (/srv/node_modules/request-promise-core/lib/plumbing.js:104:33)
at Request.RP$callback [as _callback] (/srv/node_modules/request-promise-core/lib/plumbing.js:46:31)
at Request.self.callback (/srv/node_modules/request/request.js:185:22)
at emitTwo (events.js:126:13)
at Request.emit (events.js:214:7)
at Request.<anonymous> (/srv/node_modules/request/request.js:1161:10)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at IncomingMessage.<anonymous> (/srv/node_modules/request/request.js:1083:12)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
My problem i that I get an error telling me I can't make post request. I use the insertDocuments function to insert messages into a database. I am attempting to make a promise oriented version of the 'mongolab-data-api' node.js module. I apologize if my question is confusing
//This is a function in a class that handles all mlab related things
var rp = require('request-promise')
var insertDocuments = options => {
if (!options.database || !options.collectionName || !options.documents) throw new Error('Database name, Collection Name, and Document(s) are required')
var opt = {
uri: `https://api.mongolab.com/api/1/databases/${options.database}/collections`,
qs: {
apiKey: this.apiKey
},
method: 'POST',
body: {
documents: options.documents
},
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
return rp(opt)
}
var options = {
database: 'lexybase',
collectionName: 'evy-history',
documents: msg
}
insertDocuments(options)
I get this error:
Unhandled rejection StatusCodeError: 405 - {"message":"POST not allowed."}
at new StatusCodeError (/rbd/pnpm-volume/b50cbf1c-9de1-48a8-8200-48301efdd80c/node_modules/.registry.npmjs.org/request-promise-core/1.1.1/node_modules/request-promise-core/lib/errors.js:32:15)
at Request.plumbing.callback (/rbd/pnpm-volume/b50cbf1c-9de1-48a8-8200-48301efdd80c/node_modules/.registry.npmjs.org/request-promise-core/1.1.1/node_modules/request-promise-core/lib/plumbing.js:104:33)
at Request.RP$callback [as _callback] (/rbd/pnpm-volume/b50cbf1c-9de1-48a8-8200-48301efdd80c/node_modules/.registry.npmjs.org/request-promise-core/1.1.1/node_modules/request-promise-core/lib/plumbing.js:46:31)
at Request.self.callback (/rbd/pnpm-volume/b50cbf1c-9de1-48a8-8200-48301efdd80c/node_modules/.registry.npmjs.org/request/2.88.0/node_modules/request/request.js:185:22)
at emitTwo (events.js:126:13)
at Request.emit (events.js:214:7)
at Request.<anonymous> (/rbd/pnpm-volume/b50cbf1c-9de1-48a8-8200-48301efdd80c/node_modules/.registry.npmjs.org/request/2.88.0/node_modules/request/request.js:1161:10)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at IncomingMessage.<anonymous> (/rbd/pnpm-volume/b50cbf1c-9de1-48a8-8200-48301efdd80c/node_modules/.registry.npmjs.org/request/2.88.0/node_modules/request/request.js:1083:12)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
Edit: As it turns out, the problem was that collectionName need3d to be specified and it shoul have been
body: options.documents
instead of
body: {
documents:options.documents
}
You are missing the collection name in uri:
uri: https://api.mongolab.com/api/1/databases/${options.database}/collections
should be:
uri: https://api.mongolab.com/api/1/databases/${options.database}/collections/{collectionName}
just change the collectionName
405 is returned from mongolab API
I am trying to get 200 status code in response, but as a result it's ETIMEDOUT.
I can't understand, how is it possible that I can grab successful response via postman, but same via node-fetch responding with ETIMEDOUT always.
Here is an example of code:
const Resource = {
get: cb => {
fetch('https://example.com', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: {...some body...},
}).then(res => {
if (res.status !== 200) cb(`Status: ${res.status}, ${res.statusText}`)
return res.text()
}).then(data => {
cb(null, data)
}).catch((err) => {
console.log('ERROR: ', err)
})
}
}
and here is response:
ERROR: { FetchError: request to https://example.com failed, reason: connect ETIMEDOUT
at ClientRequest.<anonymous> (C:\Users\projects\DSSRQ\node_modules\node-fetch\lib\index.js:1393:11)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
message: 'request to https://example.com failed, reason: connect ETIMEDOUT',
type: 'system',
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT' }
It looks like it was because of the proxy limitation.