Express routes giving 500 internal server - javascript

my server can't find the api's that i created in api directory. it leads to 500 internal server.
I have checked routes.js but i see that everything is right. i have an error.js file for file handling. Here's my code.
'use strict';
let router = require('express').Router();
// Middleware
let middleware = require('./controllers/middleware');
router.use(middleware.doSomethingInteresting);
// Tasks
let tasks = require('./controllers/tasks');
let createkeypairs = require('./controllers/createkeypairs');
let importaddress = require('./controllers/importaddress');
let getwalletinfo = require('./controllers/getwalletinfo');
router.get('/tasks', tasks.findAll2);
router.get('/createkeypairs', createkeypairs.findAll);
router.get('/importaddress', importaddress.findAll);
router.get('/getwalletinfo', getwalletinfo.findAll);
router.post('/buggyroute', tasks.buggyRoute);
// Error Handling
let errors = require('./controllers/errors');
router.use(errors.errorHandler);
// Request was not picked up by a route, send 404
router.use(errors.nullRoute);
// Export the router
module.exports = router;
now showing you my createkeypairs.js
'use strict';
let errors = require('./errors.js');
var request = require("request");
var options = { method: 'POST',
url: '127.0.0.1:18332',
headers:
{ 'Authorization': 'Basic bXVsdGljaGFpbnJwYzpHTmJ5enJhMnlHRjN4Ymp1cnluRTFucTlnV1ExRXV3OTFpYVBqSkt5TkJxdA==',
'cache-control': 'no-cache',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json' },
body: { method: 'createkeypairs', params: [], chain_name: 'tokenchain' },
json: true };
exports.findAll = (req, res, next) => {
// Simulate task list, normally this would be retrieved from a database
let createkeypairs ;
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log("working here ");
// res.json(body);
});
};
exports.buggyRoute = (req, res, next) => {
// Simulate a custom error
next(errors.newHttpError(400, 'bad request'));
};

I think the problem is in createkeypair file.
Try this code once for your createkeypairs.js:
'use strict';
let errors = require('./errors.js');
var request = require("request");
let config = require('config');
var auth = 'Basic ' + Buffer.from(config.user + ':' + config.pass).toString('base64');
var url = config.url;
var chain = config.chain;
var options = { method: 'POST',
url: url,
headers:
{ 'cache-control': 'no-cache',
Authorization : auth,
'Content-Type': 'application/json' },
body: { method: 'importaddress', params: ["address"], chain_name: chain },
json: true };
exports.findAll = (req, res, next) => {
// Simulate task list, normally this would be retrieved from a database
let createkeypairs ;
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
res.json(body);
});
};
exports.buggyRoute = (req, res, next) => {
// Simulate a custom error
next(errors.newHttpError(400, 'bad request'));
};
Do tell me if it works or not.

Related

Next JS API Routes add query on Client side

I am fetching IGDB api on server because I need to go through CORS. I am using async await connected to client side. Everything works fine but I need to pass query like '/?fields=cover.*,name;limit=50;' to https://api.igdb.com/v4/games from client side, not from server. When I am adding a query to client side, it's still showing the query only from server. How I can pass this query from client side? This is my code:
api/example.js
import Cors from "cors";
import initMiddleware from "../../components/init-middleware";
const cors = initMiddleware(
Cors({
methods: ['GET', 'POST', 'OPTIONS'],
})
)
const settings = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Client-ID': 'my_client-id',
'Authorization': 'Bearer my_authorization',
},
}
const remoteServerUrl = 'https://api.igdb.com/v4/games'
export default async function handler(req, res) {
await cors(req, res)
const response = await fetch(remoteServerUrl, settings);
const data = await response.json()
res.json(data)
}
client side
const settings = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Client-ID': 'my_client-id',
'Authorization': 'Bearer my_authorization',
},
const fetchData = async () => {
let query = '/api/example/'
const response = await fetch(query + HERE I WANT TO ADD QUERY, settings);
const data = await response.json();
}
Edit:
Status Code: 308 Permanent Redirect
initMiddleware
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
export default function initMiddleware(middleware) {
return (req, res) =>
new Promise((resolve, reject) => {
middleware(req, res, (result) => {
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}

Post request with node js

I'm trying to make a post request with node.js and when I try to run it, I get the data to show up in the console but noot the body of my HTML. In the console I get the error
app.js:4 POST http://localhost:8000/addAnimal net::ERR_EMPTY_RESPONSE
postData # app.js:4
(anonymous) # app.js:25
app.js:21 Uncaught (in promise) TypeError: Failed to fetch
It seems like the function is working but not the actual post request part. I can't for the life of me figure out what I'm doing wrong.
This is my code:
server.js:
projectData = {};
/* Express to run server and routes */
const express = require('express');
/* Start up an instance of app */
const app = express();
/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
/* Initialize the main project folder*/
app.use(express.static('project1'));
const port = 8000;
/* Spin up the server*/
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
// GET route
app.get('/all', sendData);
function sendData (request, response) {
response.send(projectData);
};
// POST route
app.post('/add', callBack);
function callBack(req,res){
res.send('POST received');
}
// POST an animal
const data = [];
// TODO-Call Function
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body)
})
app.js
/* Function to POST data */
const postData = async ( url = '', data = {})=>{
console.log(data);
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json()
// console.log(newData);
return newData.json()
}catch(error) {
console.log("error", error)
// appropriately handle the error
};
};
// TODO-Call Function
postData('/addAnimal', {animal:'lion'});
Any help would be greatly appreciated.
Thanks,
Mike
💡 The only one reason why you got message like it, it's because you never send response to the client.
👨‍🏫 So, You should to send response to the client. For an example, you can look at this code below: 👇
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
// send data to client
// you can change req.body with the object what you want to sent do the client
res.status(200).send(req.body);
})
📤 Update: Addtional information
Make sure you call the endpoint: http://localhost:8000/addAnimal.
Frontend: Make sure your code like this code below
const postData = async ( url = '', data = {})=>{
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
console.log(await response.json());
return await response.json()
}catch(error) {
console.log("error", error);
};
};
I hope it can help you 🙏.
Try this:
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
res.send('done'); // send response
});
Change the app.js code with the below.
/* Function to POST data */
const postData = async (url = "", data = {}) => {
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
try {
return response.json();
} catch (error) {
console.log("error", error);
// appropriately handle the error
}
};
// TODO-Call Function
(async function(){
let res = await postData("/addAnimal", { animal: "lion" });
console.log(res);
})();
And also change the post method like below.
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
res.status(200).send(data);
})

Is there a way for filer API endpoint JSON response?

I have an external API endpoint that uses basic authentication that I'm trying to find a specific key and/or value of from the JSON response.
Results:
hrefsOnly returns an array with two items.
[
"https://192.168.254.133/api/json/v2/types/volumes/1",
"https://192.168.254.133/api/json/v2/types/volumes/3"
]
Calling hrefsOnly[1] shows the following JSON response:
{ "content": {
"ancestor-vol-name": null,
"small-io-alerts": "disabled",
"last-refreshed-from-obj-name": null,
"small-iops": "0",
"wr-latency": "1738",
"obj-severity": "information"
}}
volumeInfo is undefined in my code is below:
const express = require('express');
const app = express();
const request = require("request");
const bodyParser = require('body-parser');
const auth = 'YWRtaW46WHRyZW0xMA==';
//Get Volume api endpoint values
var getVols = {
method: 'GET',
url: 'https://192.168.254.133/api/json/v2/types/volumes/',
headers:
{
'cache-control': 'no-cache',
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`
}
};
//Get above api endpoint data
var volsData = {
method: 'GET',
url: 'https://192.168.254.133/api/json/v2/types/volumes/1',
headers:
{
'cache-control': 'no-cache',
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`
}
};
var hrefsOnly = [];
var volumeInfo = [];
//GET request to parse hfref data only
request(getVols, function (error, response, body) {
var data = JSON.parse(body);
if (error){
console.log('error: ', error);
} else {
for(var i = 0; i < data["volumes"].length; i++){
hrefsOnly.push(data["volumes"][i].href);
}
}
});
app.get('/url', (req, res, next) => {
res.send(hrefsOnly);
});
// GET Volumes JSON response
request(volsData, function (error, response, body) {
var vols = body;
if (error){
console.log('error: ', error);
} else {
for(var elem in vols){
volumeInfo.push(vols);
}
}
});
app.get('/volume', (req, res, next) => {
console.log(volumeInfo["content"]);
res.send(volumeInfo["content"]);
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
app.listen(3000, () => {
console.log("Server running on port 3000");
});
I expect when I visit the page localhost:3000/volume to return the content section from the API. the page shows blank though.
console.log(volumeInfo[1]) shows the JSON data, but volumeInfo[1].content is undefined. Not sure what I'm doing to get 'undefined' as the result.
You declared an array var volumeInfo = []; but you're using it as a map res.send(volumeInfo["content"]);
TTo access an element inside an array, you need an index (integer). Try with res.send(volumeInfo[0].content);

React Fetch for a Node program

I have a fetch on React client program which is as below:
checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response
} else {
var error = new Error(response.statusText)
error.response = response
throw error
}
};
componentDidMount() {
console.log('in the did mount ' +this.state);
return fetch('/addUser', {
method: 'put',
body: JSON.stringify(this.state),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(this.checkStatus)
.then(()=>console.log('updated!!!'))
};
This is App.jsx.
In the Node End of the project I have addUser.js under routers folder, which has the code below:
let router = require('express').Router(); let bodyParser =
require('body-parser');
// parse application/json router.use(bodyParser.json());
router.put('/addUser', update);
function update(req, res) { console.log('updating-', req.body);
res.sendStatus(200); }
The client page is returning:
resource not found: http://localhost:3000/addUser
Is there any config that I am missing in the above.
I have this on a react node project.

How to resolve NODE.Js HTTP POST "ECONNRESET" Error

I have this function and the below data which is passed into this function returns a ECONNRESET, socket hang up error. However, when the discountCode array is reduced to like only 10 objects, it can POST without any problem.
What could the cause for this problem? I tried to do multiple req.write() by segmenting the data in Buffer, however that doesn't work out well. Any NodeJs ninja could give some insights to this problem?
createObj: function(data, address, port, callback) {
//console.log('Create Reward: '+JSON.stringify(data));
var post_data = JSON.stringify(data);
var pathName = '/me/api/v1/yyy/'+data.idBusinessClient+'/newObj';
//
var options = {
hostname: address,
port: port,
path: pathName,
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'en-US,en;q=0.8'
}
};
// http call to REST API server
var req = restHttp.request(options, function(res) {
console.log('HTTP API server PUT Reward response received.');
var resData = '';
res.on('data', function(replyData) {
// Check reply data for error.
console.log(replyData.toString('utf8'));
if(replyData !== 'undefined')
resData += replyData;
});
res.on('end', function() {
//<TODO>Process the data</TODO>
callback(JSON.parse(resData));
});
});
req.write(post_data);
req.end();
console.log('write end');
req.on('close', function() {
console.log('connection closed!');
});
req.on('error', function(err) {
console.log('http request error : '+err);
callback({'error':err});
throw err;
});
req.on('socket', function(socket) {
console.log('socket size:'+socket.bufferSize);
socket.on('data', function(data) {
console.log('socket data:'+data);
});
});
}
]}`
I had the same problem and was able to resolve it by adding a Content-Length header:
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(post_data),
'Accept': 'application/json',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'en-US,en;q=0.8'
}
However, I still have no clear idea why a missing Content-Length header causes such a trouble. I assume it's some kind of weirdness in the internal Node.js code. Maybe you can even call it a bug, but I'm not sure about that ;)
PS: I'm absolutely interested more information about the cause of this problem. So please leave a comment if you have any idea...
When you change the content of response for sure you need also to update on header the content length:
headers: {
...
'Content-Length': Buffer.byteLength(post_data),
...
}
But i run on this problem also when i try to make multiple request and seems that this is not well managed on different library so a workaround that i have found if this problem persist is to add on headers:
headers: {
...
connection: 'Close'
...
}
So if you are making request on different servers.. this close the connection after finish the process. This worked for me in net, node-http-proxy.
If Express and http-proxy-middleware is used to make the POST call, and some body parser middleware is used like express.json(), the request interceptor fixRequestBody must be used (more info). Otherwise the POST call will hang with the ECONNRESET error.
const express = require('express');
const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware');
const app = express();
app.use(express.json());
app.post(
'/path',
createProxyMiddleware('/path', {
target: API_URL,
changeOrigin: true,
pathRewrite: (path, req) => `/something/${req?.body?.someParameter}`,
onProxyReq: fixRequestBody // <- Add this line
});
Had the same problem. The solution for me was to append it to the proxy for it to work. If you're not using a proxy, you can probably just append it to the post request itself.
With proxy:
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import logger from './logger';
// setup routes
server.get('/isAlive', (req, res) => res.send('Alive'));
server.get('/isReady', (req, res) => res.send('Ready'));
server.use(express.static(path.join(__dirname, '../build')));
const restream = (proxyReq, req, res, options) => {
if (req.body) {
let bodyData = JSON.stringify(req.body);
proxyReq.setHeader('Content-Type', 'application/json');
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
}
};
server.use(
'/api',
createProxyMiddleware({
target: 'http://your-backendUrl-api',
onProxyReq: restream,
changeOrigin: true,
proxyTimeout: 30000,
secure: true,
logLevel: 'info',
onError: (err, req, res) => {
logger.error('error in proxy', err, req, res);
},
})
);
E.g without proxy:
import axios, { AxiosResponse } from 'axios';
const api = axios.create({
baseURL: '/api/....',
timeout: 35000,
withCredentials: true,
headers: { Pragma: 'no-cache', 'Cache-Control': 'no-cache' },
validateStatus: (status) => status < 400,
});
const response = await api.post(
`/somepath/${exampleInjectedId}/somepathToRestAPI`,
{
...payload
},
{
baseURL: '/api/...',
timeout: 35000,
withCredentials: true,
headers: {
Pragma: 'no-cache',
'Cache-Control': 'no-cache',
'Content-Length': Buffer.byteLength(
JSON.stringify({
...payload
})
),
},
validateStatus: (status) => status < 400,
}
);

Categories

Resources