I have an application using NodeJS in backend and specifically Express framework to serve API routes. My client side is written in ReactJS, making use of axios to make API requests.
First time using axios package, and i can't find how to access error messages from the response.
My API returns as error responses:
res.status(404).send({ error: 'Error Message' });
In axios i have:
axios.post('/api/users', newUser)
.then((user) => {
console.log(`User created: ${JSON.stringify(user)}`);
}).catch((err) => {
console.log(`Error : ${JSON.stringify(err)}`);
});
console.log(`Error : ${JSON.stringify(err)}`) prints:
{
"message": "Request failed with status code 404",
"name": "Error",
"stack": "Error: Request failed with status code 404\n at createError (http://localhost:3000/static/js/0.chunk.js:13853:15)\n at settle (http://localhost:3000/static/js/0.chunk.js:14074:12)\n at XMLHttpRequest.handleLoad (http://localhost:3000/static/js/0.chunk.js:13328:7)",
"config": {
"url": "/api/users",
"method": "post",
"data": "someData",
"headers": {
"Accept": "application/json, text/plain, */*",
"Authorization": "Bearer xxxxx",
"Content-Type": "application/json;charset=utf-8"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1
}
}
I can't find nowhere in that err object the response message from the server, i have even tried:
res.status(404).json({ error: 'Error Message' });
with no success.
Per this comment, try accessing err.response in the catch block.
The err.response would have an object { error: 'Error Message' } so you can access that using err.response.error. also make sure err.response.error exists because if it doesn't and you try to access it will throw an error inside the catch saying err.response.error is undefined
axios.post('/api/users', newUser)
.then((user) => {
console.log(`User created: ${JSON.stringify(user)}`);
}).catch((err) => {
if(err.response.error)
console.log(`Error : ${JSON.stringify(err.response.error)}`);
});
Related
I am working on a chrome extension that creates an Anki card and adds it to my desk.
Right now am I trying to get the request to work using the Anki API.
For some reason the server is denying my request.
Here is my code (JavaScript) to create a card and send it as a request to the localhost:
async function createCard() {
// Set the Anki API endpoint URL
const baseURL = 'http://localhost:8765';
// Set the Anki API action, version and params
const card = {
"action": "addNote",
"version": 6,
"params": {
"note": {
"deckName": "Default",
"modelName": "Basic",
"fields": {
"Front": "front content",
"Back": "back content"
},
"options": {
"allowDuplicate": false,
"duplicateScope": "deck",
"duplicateScopeOptions": {
"deckName": "Default",
"checkChildren": false,
"checkAllModels": false
}
}
}
}
};
// Send the request to the Anki API
try {
const response = await fetch(baseURL, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(card)
});
// Check the status code of the response
if (response.ok) {
console.log('Card created successfully');
} else {
console.error(`Error creating card: ${response.statusText}`);
}
} catch (error) {
console.error(`Error creating card: ${error}`);
}
}
(The card by now is hardcoded.)
When I execute this code I get 2 errors thrown by chrome:
POST http://localhost:8765/ net::ERR_ABORTED 403 (Forbidden)
Error creating card:
The first error happens on the fetch function
and the second error at "console.error('Error creating card: ${response.statusText}');"
I suggest that the second error appears due to the first one.
Since I am new to computer science, all I tried so far is checking the logs of ANKI to find information about the error, but I couldn't find something. I tried different syntax to create the card since I pass this into the fetch function where the error occurs.
The localhost is running while I am working on this, so the server is accessible.
My solution is setting the webCorsOriginList config of AnkiConnect as "*"
"webCorsOriginList": ["*"]
It will allow CORS for all domains.
I started playing around with the Philips Hue Bridge API by sending it requests using Postman. I was able to authenticate myself, create a user and even successfully turn lights on or off.
Conclusion: I am able to reach the API.
Next I made a mini test javascript file to do the exact same using Node.js and axios#0.21.4. When I try the following code everything works and I receive the expected JSON responses:
const axios = require('axios')
axios({
method: 'GET',
url: 'http://philips-hue.local/api/BYLCIlxABzz2eDHAxx70T'
})
.then(({data}) => {
console.log('------> AXIOS RES: ', data)
})
.catch((err) => {
console.log('------> AXIOS ERR: ', err)
})
Conclusion: Axios is able to communicate with the API.
Next I wanted to build this into an Express.js endpoint. However when I try to use the same code inside of express#4.17.1 I get an error:
router.route('/getlights').get((req, res) => {
axios({
method: 'GET',
url: 'http://philips-hue.local/api/BYLCIlxABzz2eDHAxx70T/lights'
})
.then(({data}) => {
console.log('------> AXIOS RES: ', data)
res.json({
state: 'SUCCESS',
data
})
})
.catch((err) => {
console.log('------> AXIOS ERR: ', err)
res.json({
state: 'ERROR',
err
})
})
})
Response:
{
"state": "ERROR",
"err": {
"message": "connect EHOSTUNREACH 192.168.0.107:80",
"name": "Error",
"stack": "Error: connect EHOSTUNREACH 192.168.0.107:80\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)",
"config": {
"url": "http://philips-hue.local/api/BYLCIlxABzz2eDHAxx70T/lights",
"method": "get",
"headers": {
"Accept": "application/json, text/plain, */*",
"User-Agent": "axios/0.21.1"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1
},
"code": "EHOSTUNREACH"
}
}
I started troubleshooting the problem by first trying to changing the URL to a random online place holder like http://jsonplaceholder.typicode.com/posts/1 just to see if I could establish any connection at all. This actually worked right away.
This is where I got really confused. Why am I able to successfully communicate with the bridge using Postman or Axios in a javascript file, but NOT able to connect with it when the same Axios code is used by express. The problems seems to occur only when using both axios and express to connect to the bridge API.
I have already tried retesting this with node-fetch and 3 other versions of Axios. All tests failed the exact same way. The code by itself can always connect to the API but once the code is being called by express it causes the EHOSTUNREACH error.
I ran out of ideas on how to further google this issue since I am not sure what exactly is causing the problem (express and/or axios and/or bridge). Any trouble shooting ideas or google keywords are also very welcome. :)
I had the same error, for some reason the ip address of my hue bridge had changed so I went into the hue app on my smartphone and copied the new ip address. IDK if this is helpfull, im pretty new here.
I had the same error since yesterday, and couldn't find solution. What actually caused mine was, there was a bearer token on the 3rd party api I called and i also pass it through the header as well.
So it was removed and pass the token through header and it works fine.
UPDATE: error keeps showing up if send another request.
The solution i found was to use request.
const request = require('request');
const headers = {
'Content-Type': 'application/json',
'token': `${token}`
};
const data = {
username : 'username'
}
let options = {
method: 'POST',
url: 'url',
port: 443,
headers: headers,
body: data,
json: true
};
request(options, async (error, res, body) => {
if (error) {
console.log({error});
return response.status(500).json({
status: false,
message: "Error occured"
});
} else {
console.log({body});
return response.status(201).json({
message: "success"
});
}
});
so I want to make search request to my elastic enterprise search app using guide from the documentation in here , I don't want to use elastic node JS client, but I want to make http request using axios.
here is the code I use
const url = "https://XXXXXXX38ce49e5aff1aa238e6f9195.ent-search.asia-southeast1.gcp.elastic-cloud.com/api/as/v1/engines/events/search"
const headers = {"Authorization": "Bearer search-qpz4bu5o7ubb8j31r15juyrh"}
const jsonData = {
query: "hello there"
}
try {
const {data} = await axios.post(url,jsonData,headers)
response.status(200).send(data)
} catch (error) {
console.log(error)
response.status(500).send(error)
}
but I always get 401 error like this:
{
"message": "Request failed with status code 401",
"name": "Error",
"stack": "Error: Request failed with status code 401\n at createError (/Users/xxx/Documents/elastic_jxxx/firebase_emulator/functions/node_modules/axios/lib/core/createError.js:16:15)\n at settle (/Users/xxxx/Documents/elastic_jakarta_kumpul_muslim/firebase_emulator/functions/node_modules/axios/lib/core/settle.js:17:12)\n at IncomingMessage.handleStreamEnd (/Users/xxxxx/Documents/elastic_xxxxx/firebase_emulator/functions/node_modules/axios/lib/adapters/http.js:244:11)\n at IncomingMessage.emit (events.js:203:15)\n at endReadableNT (_stream_readable.js:1145:12)\n at process._tickCallback (internal/process/next_tick.js:63:19)",
"config": {
"url": "https://XXXXXXXa638ce49e5aff1aa238e6f9195.ent-search.asia-southeast1.gcp.elastic-cloud.com/api/as/v1/engines/events/search",
"method": "post",
"data": "{\"query\":\"hello there\"}",
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
"User-Agent": "axios/0.20.0",
"Content-Length": 28
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"Authorization": "Bearer search-qpz4bu5o7ubb8j31r15juyrh"
}
}
I believe I have put the correct search key, I can get the sucessful response using the same baseURL and search key in postman like this
what went wrong in here ?
The headers need to be passed as a named object in the config part.
So try it like this:
const {data} = await axios.post(url, jsonData, { headers: headers })
or even more concisely:
const {data} = await axios.post(url, jsonData, { headers })
Tip: Postman is capable of pre-constructing axios requests when you click on Code. So next time you're not sure, Postman is here to help:
I have an API call in POSTMAN, which I am trying to replicate in nodeJS project using Axios, but the result is not the same that of a POSTMAN.
The call looks like this in POSTMAN:
Inside the body element I have: models and values properties and Authorization is of type Bearer .
I get a response result as an array.
Now, I try to do the same using axios, but I get error:
Code
axios.defaults.baseURL = 'http://XXXXXXXXXXXXXXX:8069/api';
axios({
method: 'POST',
url: '/create/res.users',
data: {
models: 'res.users',
values: "{ 'login': 'john#gmail.com', 'name':'john', 'email':'john#gmail.com', 'password': '123123123' }"
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + accessToken
},
})
.then(function (response) {
console.log("Register", response);
res.status(200).send({
message: response.data
});
})
.catch(function (error) {
console.log("Error", error.response.data);
res.status(error.response.status).send({
message: error.response.data
});
});
Error
{
"message": {
"name": "odoo.exceptions.RedirectWarning",
"message": "You cannot create a new user from here.\n To create new user please go to configuration panel.\n74\nGo to the configuration panel",
"arguments": [
"You cannot create a new user from here.\n To create new user please go to configuration panel.",
74,
"Go to the configuration panel"
],
"exception_type": "error",
"code": 500,
"description": "Restful API Error"
}
}
By default, axios serializes JavaScript objects to JSON. To send data in the application/x-www-form-urlencoded format instead, This document may help you:
https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format
My nock call looks like as below
app_url='myshop.app.com'
result = nock(app_url, {
reqheaders: {
"content-type": "application/json",
'authorization': 'Basic Auth'
}
})
.get('/admin/products.json?collection_id=10001&limit=250&fields=id')
.reply(200, {
"products": [
{ "id": 101},
{"id": 102},
]
});
Resolve :
(node:1378) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Nock: No match for request { .
But now,
==========updated=============
I have updated my call which is not throwing an error but now it is not intercepting the request....It is still hitting shopify to fetch the data
Just add flag in scope { allowUnmocked: true }
nock('https://host.com', { allowUnmocked: true })
.post(`/path`)
.reply(200, {answer: "any"});
This happens when a nock matching the URL being hit is not found.
The url being hit is
https://myshop.app.com/admin/products.json?collection_id=201&limit=10&fields=id
as seen in the error message.
The URLs you are nocking do not correspond to it.
Something like this should work.
app_url = "https://myshop.app.com/"
result = nock(app_url, {
reqheaders: {
"content-type": "application/json",
}
})
.get('/admin/products.json?collection_id=201&limit=10&fields=id').
.reply(200, {
"products": [{
"id": 101
}, {
"id": 102
}, ]
});
More details about the exact way to nock can be found in the Nock Documentation.
The nocked URL must be exactly the same as the URL that would be executed by Node in order to avoid the 'Nock: No match for request' error. So all you need to do is:
nock('https://host.com')
.log(console.log) // log the mocked URL so that you will know if they're
// the same or not.
.post(`/path`)
.reply(200, {answer: "any"});